2012-06-22 33 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