2012-06-15 52 views
0

目標:跨線程問題更新數據源

一旦我在我的用戶界面上的啓動按鈕點擊,我目前火兩個背景的工人。

BGWorker 1是負責調用的.dll方法抓取網站 BGWorker 2負責更新使用數據源=源設置器

問題在DataGridView:

我的DLL接收作爲參數,這是對.dll運行時將填充的數據源的引用。所以基本上,.dll會偶爾在數據源中添加一個對象,直到它完成運行。

的BGWorker 2執行此:

while (1 == 1) // Runs until is it manually disposed 
{ 
    CoursesGrid.BeginInvoke // inline method 
    (
     (Action) delegate 
     { 
      if (_coursesSource.Count > 0) // if source is not empty,Binds. 
      { 
       try 
       { 
        CoursesGrid.DataSource = _coursesSource; 
        CoursesGrid.EndEdit(); 
       } 
       catch (Exception ex) 
       { 
        Logs.LogWriter.LogError(ex); 
       }     
      } 
      else 
      { 
       // Signals User To keep Waiting 
      } 
     } 
    ); 
Thread.Sleep(4000); 

行爲流量:

  • DLL被調用
  • 方法分析一個元件,並且增加了源
  • 最終,BGWorker 2喚醒並將DataGridView源綁定到修改後的源代碼
  • DLL的螺紋一直解析但一旦它試圖將新元素添加到源

TL失敗:DR: 線程1上寫入源 線程2讀該修改的源,並將其綁定到DataGridView中它會刷新 線程1失敗源上寫一遍:

"Cross-thread operation not valid: Control 'CoursesGrid' accessed from a thread other than the thread it was created on."} 

兩個線程都處理相同來源,但BGWorker 2,只有它綁定到接口,這應該是工作。想知道這裏會發生什麼?

+2

我在猜測某些東西不能按照你想要的方式工作,也許你可以告訴我們什麼是或者不在工作以及錯誤是什麼。 – CodingGorilla

+1

btw,fyi,在C#3.0中,您可以編寫「BeginInvoke((=){...})' – abatishchev

+0

@CodingGorilla編輯。對不起,如果它不是第一次清楚。 增加了一個TL:DR –

回答

2

我認爲正在發生的事情是您將數據網格綁定到您的_coursesSource,這會導致數據網格顯示第一行。然後,稍後,您正在修改相同的_coursesSource實例,該實例可能觸發導致數據網格嘗試自行更新(即顯示新添加的行)的屬性更改或集合更改通知。

但是由於修改正在另一個線程上發生,數據網格「聽到」並響應的事件也發生在導致跨線程違規的後臺線程上。

你需要做的是:a)將添加到_coursesSource的元素編組到UI線程(它聽起來不像你可以輕易做到的),或者b)綁定到_coursesSource的副本,然後在你的BGWorker 2,每次更新_coursesSource將網格重新綁定到新副本,這樣網格永遠不會「聽到」更改通知,它總是綁定到集合的新副本。這不是最有效的方式,但它應該爲你完成工作。

+0

剛剛嘗試了第二種方法。 在BGWorker 2上,我得到對_coursesSource的引用,將它複製到一個「temp」BindingSource,並將GridView綁定到「temp」BindingSource。 仍然有同樣的問題。 您可能會想到的其他方法? –

+0

您可以使用新代碼更新您的帖子,並明確指出發生異常的位置嗎? – CodingGorilla

+0

你去那裏:http://pastebin.com/TwAh0UtK 希望它有幫助 –