2012-06-22 32 views
1

我有一些數據,我更新它在一個任務:該應用程序是一個黑客現在的想法,所以代碼道歉。從後臺更新datagridview線程奇怪的行爲

Task.Factory.StartNew(() => 
    { 
     dataGridView1.BeginInvoke((Action)(() => 
      { 
       dataGridView1.SuspendLayout(); 
      })); 

     dataSet1.Reset(); 
     da.Fill(dataSet1); 

     dataGridView1.BeginInvoke((Action)(() => 
      { 
       dataGridView1.DataSource = dataSet1.Tables[0]; 
       dataGridView1.Columns[0].Visible = false; 
       dataGridView1.Columns[1].Width = 50; 
       dataGridView1.ResumeLayout(); 
      })); 
    } 
    ).ContinueWith(task => 
     { 
      if (dataSet1.Tables[0].Rows.Count > 0) 
      { 
       if (lastcount != dataSet1.Tables[0].Rows.Count) 
       { 
        lastcount = dataSet1.Tables[0].Rows.Count; 
        if (lastcount == 0) 
        { 
         NotifyWithMessage("The items have been cleared", "Items cleared"); 
        } 
        else 
        { 
         NotifyWithMessage(String.Format("There are {0} new items in your monitor", dataSet1.Tables[0].Rows.Count)); 
        } 
       } 
      } 
     } 
    ); 

現在,代碼從根本上起作用。沒有錯誤,這是不錯的..

當它在一個任務外更新時,根本沒有datavgridview的閃爍,當我在調試中運行它,它是非常小的,並且在hack可接受的範圍內。那時我在調試之外運行它......這非常明顯!暫停和恢復佈局完全沒有任何區別。我需要線程中的代碼,因爲UI沒有響應 - 雖然它是可以接受的,但它現在有不好的刷新。

我Datagridview是根據單元格顏色自定義顏色,但是,我只是不明白爲什麼有調試和發佈之間的區別,我期望性能相反!

(我試過調用和BeginInvoke的...)

我看着Horrible redraw performance of the DataGridView on one of my two screens

而下的調試,這不閃爍可言,甚至有點...在釋放條件,有一個荒謬的閃爍...

我該怎麼辦?

回答

1

最後繼承人我做了什麼: 我把查詢重新排列成一個新的數據集,如果計數是一樣的,那麼我沒有更新網格,如果計數已經改變了,我做了。

timer1.Stop(); 

     Task<Boolean>.Factory.StartNew(() => 
      { 
       DataSet t = new DataSet(); 
       //_dataSet1.Reset(); 
       Boolean ok = false; 
       Int16 retries = 0; 
       while (!ok && retries<3) 
       try 
       { 
        da.Fill(t); 
        ok = true; 
       } 
       catch 
       { 
        retries++; 
        Thread.Sleep(1000); 
       } 
       //if (!ok) throw new Exception("DB error"); 
       if (!ok) return false; 
       try 
       { 
        if (t.Tables.Count > 0 && t.Tables[0].Rows.Count != _lastcount) 
        { 
         _dataSet1 = t; 
         _lastcount = t.Tables[0].Rows.Count; 
         return true; 
        } 
       } 
       catch { } 
       return false; 
      }).ContinueWith(task => 
       { 
        if (task.IsFaulted) 
        { 
         SQLFailed(); 
         return; 
        } 
        if (!task.Result) return; 


        Invoke((Action) (() => 
             { 
              dataGridView1.DataSource = _dataSet1.Tables[0]; 
              dataGridView1.Columns[0].Visible = false; 
              dataGridView1.Columns[1].Width = 50; 
             })); 

        if (_lastcount == 0) 
        { 
         NotifyWithMessage("The items have been cleared", "Items cleared"); 
        } 
        else 
        { 
         NotifyWithMessage(String.Format("There are {0} new items in your monitor", _lastcount)); 
        } 
       }); 


    timer1.Start(); 
2

啓動後臺填充數據集的任務,完成此任務後,執行BeginInvoke,在其中暫停佈局,分配數據並繼續。

使用現在的版本,當執行代碼路徑時很難預測會發生什麼。

渲染必須在UI線程上,所以你只能嘗試優化它的代碼。和我在文章開頭描述的Async部分一樣。

+0

我想上面的代碼DID填充數據集在一個單獨的線程..因爲它是在一個任務完成.. – BugFinder