首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c# BeginInvoke问题

c# BeginInvoke问题
EN

Stack Overflow用户
提问于 2010-08-03 03:30:00
回答 4查看 2.2K关注 0票数 1

我有一个程序,它对数据库进行一些繁重的调用,然后更新UI。这会导致问题,因为在大多数情况下,这意味着UI没有响应。因此,我决定将访问数据库和更新UI的函数调用放在一个单独的线程中,所以现在我有了如下内容:

代码语言:javascript
复制
 private delegate void CallAsyncDelegate();

 private void CallGetDBValues()
 {
      // Call GetDatabaseValues in new thread
      CallAsyncDelegate callGetDatabaseValues = new 
          CallAsyncDelegate(GetDatabaseValues);
      BeginInvoke(callGetDatabaseValues);
 }

 private void GetDatabaseValues()
 {
     // Get lots of data here


     // Update UI here

 }

 ...

然而,这似乎对UI没有任何影响。我在某处读到,如果要在单独的线程中运行的代码需要更新UI,那么应该如何进行调用-这是正确的吗?我做错了什么吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-08-03 03:39:36

使用.NET框架中内置的BackgroundWorker可能会更好。

代码语言:javascript
复制
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    bw.WorkerReportsProgress = true;

    void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // update UI with status
        label1.Text = (string)e.UserState
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
         //Check for cancel
         if(e.Cancelled)
         { 
             //Handle the cancellation.
         {

         //Check for error
         if(e.Error)
         {
             //Handle the error.

         }    

        // Update UI that data retrieval is complete
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        // Get data
        //foreach to process data
        //Report progress

        bw.ReportProgress(n, message);

    }

下面是关于如何使用BackgroundWorker的MSDN文章的链接,以了解更多详细信息。感谢Henk Holterman提出的建议,包括以下内容:

http://msdn.microsoft.com/en-us/library/cc221403%28VS.95%29.aspx

票数 3
EN

Stack Overflow用户

发布于 2010-08-03 03:33:43

在"// Update UI here“中,确保使用Control.Invoke来实际执行工作--只有在使用Control.Invoke时,UI才会被UI线程”触摸“,这是必须的。

票数 1
EN

Stack Overflow用户

发布于 2010-08-03 03:41:01

BeginInvokeInvoke意味着在UI线程上运行代码。在这种情况下,如果您从UI线程调用CallGetDBValues(),您将不会获得任何东西。

通常,您将创建一个BackgroundWorker或后台线程来执行繁重的任务,它将向UI线程回调需要更新的值。

BackgroundWorker可能是更好的解决方案(参见Robaticus的答案),但这里是一个后台线程版本。

代码语言:javascript
复制
private delegate void CallAsyncDelegate();

private void button_Click( object sender, EventArgs e )
{
    Thread thread = new Thread( GetDBValues );
    thread.IsBackground = true;
    thread.Start();
}

private void GetDBValues()
{
    foreach( ... )
    {
        Invoke( new CallAsyncDelegate( UpdateUI ) );
    }
}

private void UpdateUI()
{
    /* Update the user interface */
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3391099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档