2013-05-11 87 views
-1

在我的应用程序中,我有要求通知用户有关未决应用程序的要求。跨线程操作无效:

所以在mdiParent我设置BackgroundWorker这使查询数据库得到任何未决申请,如果发现任何显示它的工具提示上MdiParent

private void button1_Click(object sender, EventArgs e) 
{ 
    backgroundWorker1.RunWorkerAsync(2000); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    fillnotification(); 
}  

public void fillnotification() 
{ 
    int pending = 0; 
    if(Program.USERPK != 0) 
    {  
     DataTable dt = nftrans.getnotification(); 
     pending = dt.Rows.Count; 

     String message = "You Have " + pending + " Applications Pending For Approval"; 

     // toolTip1.SetToolTip(lblStatus , message); 
     toolTip1.Show(message , this, lblStatus.Location); 
    } 
} 

但是当我运行的解决方案,我我得到一个例外:

跨线程操作无效:控制'MainForm'从一个线程以外的线程访问它创建的线程。

我明白它由于两个不同的线程,但不能整理出来。任何人都可以提出解决方案吗?我尝试了我在相关问题中阅读的想法但找不到正确的解决方案

+0

是那些Win Forms? – 2013-05-11 05:57:18

+0

是的winform应用程序 – 2013-05-11 06:13:41

+0

[请参阅我的答案](http://stackoverflow.com/questions/11273562/c-sharp-cross-thread-communication/11274317#11274317) – 2013-05-11 07:11:18

回答

0

更改fillnotification()以返回您的待定值,并将其传递给您的DoWork()处理程序中的“e.Result”。现在连线RunWorkerCompleted()事件并检索后台操作的结果:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     e.Result = fillnotification(); 
    } 

    public int fillnotification() 
    { 
     if (Program.USERPK != 0) 
     { 
      DataTable dt = nftrans.getnotification(); 
      return dt.Rows.Count; 
     } 
     return -1; 
    } 

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     int pending = (int)e.Result; 
     if (pending != -1) 
     { 
      String message = "You Have " + pending.ToString() + " Applications Pending For Approval"; 
      toolTip1.Show(message, this, lblStatus.Location); 
     } 
    } 
1

您正在更改工作线程上的UI(工具提示)。

这是不允许的。使用UI线程更改工具提示,方法是调用Window上的Invoke并将委托传递给更改工具提示的函数。

2

无论何时您从外部线程访问控件(后台工作人员Executes an operation on a separate thread.),都需要进行某种调用。这将在拥有底层窗口句柄的线程上执行委托。

一些简单的东西;

 this.Invoke(new MethodInvoker(delegate() 
     { 
     // toolTip1.SetToolTip(lblStatus , message); 
     toolTip1.Show(message, this, lblStatus.Location); 

     })); 

可能会为你的工作的情况下,只要你之前的代码没有访问控制,我不知道什么getnotification()在做什么。

1

由于看起来工具提示的改变发生在工作线程的确切末尾,所以您可以使用RunWorkerCompleted事件 - 您可以从那里修改UI线程,这就是此事件的设计目的。

当然克里斯bucklers Invoke解决方案也将工作。