2017-10-29 98 views
0

我在後面的主窗口代碼中設置了一個計時器,每隔10秒觸發一次。由於timer_Elapsed事件中引用的某些代碼的CPU密集度有點高,因此我將它放在await Task.Run(() =>的內部,但是,每當運行的事件運行時,UI線程都會暫時掛起。任何想法,爲什麼這將阻止用戶界面?代碼:爲什麼我的異步計時器阻塞UI線程?

async void _timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     await Task.Run(() => 
     { 
      //Update default status bar text routinely 
      try 
      { 
       if (ChecEnabled()) 
       { 
        this.Dispatcher.Invoke(() => 
        { 
         StatusText.Text = String.Format("Status: Enabled. Watching for changes…"); 
        }); 
       } 
       else 
       { 
        this.Dispatcher.Invoke(() => 
        { 
         StatusText.Text = String.Format("Status: Disabled"); 
        }); 
       } 
      } 
      catch (ObjectDisposedException) 
      { 
       //Window closed and disposed timer on different thread 
      } 

      //System Checks 
      UpdateSystemReadyStatus(); 
     }); 
    } 
+0

ChecEnabled()是CPU密集型部件嗎?你可以發佈該代碼嗎?顯示'UpdateSystemReadyStatus'也不錯。 – Enigmativity

+0

只是要清楚 - 到目前爲止,您在問題中顯示的代碼中沒有任何內容會導致您的問題。你需要顯示完整的代碼,以便我們確信給你一個很好的答案。 – Enigmativity

+0

在Timer.Elapsed處理程序中啓動任務沒有任何意義。計時器已經在後臺線程上運行。 – Clemens

回答

3

將您的Invoke更新爲InvokeAsync。另外,你是否真的需要整個方法包裝在Task

async void _timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    //Update default status bar text routinely 
    try 
    { 
     if (ChecEnabled()) 
     { 
      await this.Dispatcher.InvokeAsync(() => 
      { 
       StatusText.Text = String.Format("Status: Enabled. Watching for changes…"); 
      }); 
     } 
     else 
     { 
      await this.Dispatcher.InvokeAsync(() => 
      { 
       StatusText.Text = String.Format("Status: Disabled"); 
      }); 
     } 
    } 
    catch (ObjectDisposedException) 
    { 
     //Window closed and disposed timer on different thread 
    } 

    //System Checks 
    await Task.Run(()=>UpdateSystemReadyStatus()); 
} 
相關問題