2011-10-03 36 views
1

第一次運行我的Backgroundworker時,它運行正常 - 在後臺更新數據表,然後RunWorkerCompleted將數據表設置爲datagridview數據源。BackgroundWorker not firing RunWorkerCompleted

如果我再運行它,datagridview將清除並不會更新。我無法弄清楚爲什麼。

我已驗證數據表中包含行,當我的代碼命中dgvReadWrites.DataSource。

private void btnGenerateStats_Click(object sender, EventArgs e) 
    { 
     dtJobReadWrite.Columns.Clear(); 
     dtJobReadWrite.Rows.Clear(); 
     dgvReadWrites.DataSource = dtJobReadWrite; 

     List<Tuple<string, string>>jobs = new List<Tuple<string, string>>(); 

     foreach (ListViewItem job in lstJobs.SelectedItems) 
     { 
      jobs.Add(new Tuple<string, string>(job.Text, job.SubItems[2].Text)); 
     } 
     BackgroundWorker bgw = new BackgroundWorker(); 
     bgw.WorkerReportsProgress = true; 
     bgw.WorkerSupportsCancellation = true; 
     bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 
     bgw.DoWork += new DoWorkEventHandler(bgw_DoWork); 
     pbarGenStats.Style = ProgressBarStyle.Marquee; 
     pbarGenStats.MarqueeAnimationSpeed = 30; 
     pbarGenStats.Visible = true; 
     bgw.RunWorkerAsync(jobs); 
    } 


    private void bgw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker bgw = sender as BackgroundWorker; 
     List<Tuple<string, string>> jobs = (List<Tuple<string, string>>)e.Argument; 
     GetReadWriteStats(jobs); 
    } 

    private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     BackgroundWorker bgw = sender as BackgroundWorker; 
     bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 
     bgw.DoWork -= new DoWorkEventHandler(bgw_DoWork); 
     pbarGenStats.MarqueeAnimationSpeed = 0; 
     pbarGenStats.Value = 0; 
     pbarGenStats.Visible = false; 
     dgvReadWrites.DataSource = dtJobReadWrite; 
     dgvReadWrites.Visible = true; 
     dgvReadWrites.Refresh(); 
    } 
+1

爲什麼您明確取消訂閱RunWorkerCompleted上的事件? –

+0

去掉這個線程的建議:http://stackoverflow.com/questions/2542326/proper-way-to-dispose-of-a-backgroundworker這似乎有一個類似的問題。但是,刪除這些行並不能解決問題。 –

+0

您可以嘗試製作本地backgroundworker變量並只訂閱一次事件。然後,您不需要刪除完整方法中的處理程序 – Reniuz

回答

3
private void btnGenerateStats_Click(object sender, EventArgs e) 
{ 
    //... 
    dgvReadWrites.DataSource = dtJobReadWrite; 
    // etc... 
} 

這是一個問題,要更新dtJobReadWrite在BGW。這會導致綁定網格被工作線程更新。非法,控件不是線程安全的,只能從創建它們的線程更新。這通常會被檢查,在調試時會產生InvalidOperationException,但此檢查對綁定控件不起作用。

接下來發生了什麼事情,到處都是,你很幸運,你有一個高度可重複的僵局。更常見的不正當行爲是偶爾出現的繪畫僞影,以及只有當你不近時纔會出現死鎖。修復:

dgvReadWrites.DataSource = null; 

,並重新綁定在RunWorkerCompleted事件處理程序的網格,就像你已經這樣做了。

+0

你得到你的答案。謝謝! –

0

因爲你從這些事件中unscubscribe

bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 
bgw.DoWork -= new DoWorkEventHandler(bgw_DoWork); 

刪除這些行

0

你爲什麼要創建一個新的BackgroundWorker要運行它每一次?我希望看到如果使用BackgroundWorker的一個實例(GetReadWriteWorker或這些行的某個實例),只需訂閱一次事件,然後在btnGenerateStats_Click上運行該工作者異步,此代碼會發生什麼情況。

+0

重新使用組件只保留更多狀態。 OP在重複性方面已經存在問題。 –