2013-05-11 86 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解決方案也將工作。