2016-09-21 76 views
0

如何在不阻塞用戶界面的情況下每隔幾秒使用任務異步等待來運行任務。以下是我使用計時器的示例。我能夠每隔幾秒運行一次功能,但它阻止了用戶界面。有人可以幫助我,我是新來的異步編程。在後臺每隔幾秒鐘運行一次函數,不會阻塞用戶界面c#

private void Form1_Load(object sender, EventArgs e) 
     { 
      gridControl1.DataSource = GetData(); 
      timer.Interval = 5000; 
      timer.Tick += new EventHandler(MyTimer_Tick); 
      timer.Start(); 
     } 


     private void MyTimer_Tick(object sender, EventArgs e) 
     { 
      gridControl1.DataSource = GetData(); 
      gridControl1.RefreshDataSource(); 
     } 

     DataTable GetData() 
     { 
      DataTable dt = new DataTable(); 
      dt.Columns.Add("Value1", typeof(int)); 
      dt.Columns.Add("Value2", typeof(int)); 
      dt.Columns.Add("Value3", typeof(int)); 
      dt.Columns.Add("Value4", typeof(int)); 
      dt.Columns.Add("Value5", typeof(int)); 
      dt.Columns.Add("Value6", typeof(int)); 
      dt.Columns.Add("Value7", typeof(int)); 
      dt.Columns.Add("Value8", typeof(int)); 
      dt.Columns.Add("Value9", typeof(int)); 
      dt.Columns.Add("Value10", typeof(int)); 
      dt.Columns.Add("Value11", typeof(int)); 
      dt.Columns.Add("Value12", typeof(int)); 

      Random rnd = new Random(); 
      for (int i = 1; i < 1000000; i++) 
      { 
       dt.Rows.Add(rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), 
        rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100), 
        rnd.Next(1, 100), rnd.Next(1, 100), rnd.Next(1, 100)); 
      } 
      return dt; 
     } 
+2

您正在使用什麼版本的C#? –

+0

@RJProgrammer - 我正在使用版本4.6 – user

回答

-1

您需要先定義的GetData爲異步方法通過改變返回類型這樣做:

Task<DataTable> GetData(){...} 

也以匹配您可能要添加異步方法名指引

Task<DataTable> GetDataAsync(){...} 

那麼你可能想通過Task.Factory.StartNew

覆蓋在GetDataAsync方法的所有代碼
Task<DataTable> GetData(){ 
    return Task.Factory.StartNew(() => 
    { 
    ... 
     return dt; 
    }); 
} 

編輯: 至於重複你可能想擺脫定時器,並期待在這個答案的任務,建議通過@MrinalKamboj 使用Task.Run insted的

Task<DataTable> GetData(){ 
string result = await Task.Run(() => 
     { 
      ... 
      return dt; 

     }); 

    return result; 
} 

RepeatActionEvery Method

希望有幫助。

+1

http://blog.stephencleary.com/2013/08/startnew-is-dangerous.html,使用'Task.Run' –

+0

解決方案指出的是控制檯,不會工作Winforms,將導致調用'等待' –

+0

@MrinalKamboj true時出現死鎖,但提供的鏈接僅用於該方法本身。要使用它,他需要異步form_load並使用await關鍵字。 –

0

嘗試這樣的事情,使得這兩個事件的GetData異步

 private async void MyTimer_Tick(object sender, EventArgs e) 
     { 
      gridControl1.DataSource = await GetDataAsync(); 
      gridControl1.RefreshDataSource(); 
     } 

     public async Task<DataTable> GetDataAsync() 
     { 
       return await Task.Run(() => 
         { 
          // .... 
          return dataTable; 
         }); 
     } 
2

它看起來像您使用的是System.Forms.Timer,這引起了其在UI線程上的事件。因此,您需要將任何長時間阻塞的工作推送到後臺線程:

private async void MyTimer_Tick(object sender, EventArgs e) 
{ 
gridControl1.DataSource = await Task.Run(() => GetData()); 
gridControl1.RefreshDataSource(); 
} 
+0

這比其他解決方案更好。謝謝!! – user

+0

@user我建議Stephen提出了什麼建議,你說它效果更好。 我建議完全一樣的東西,只是它重構創建'GetDataAsync' –

+0

@MrinalKamboj:你的解決方案在執行(假)異步方法時使用'Task.Run'。我的解決方案使用'Task.Run'來調用同步方法。更多信息[here](http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html)。 –

相關問題