2017-10-29 131 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()); 
}