2012-04-07 27 views
0

我正在用异步CTP进行一些探测,但由于GUI被阻塞,我没有得到好的结果。异步CTP:我做错了,GUI被阻止

我有一个WPF应用程序的按钮和文本框的日志。然后,我有这样的代码:

private async void btnAsync01_Click(object sender, RoutedEventArgs e) 
     { 
      UpdateTxtLog("Enter in Button Async01: " + System.DateTime.Now); 
      await metodo01Async(); 
      UpdateTxtLog("Exit button Async01: " + System.DateTime.Now); 
     } 

private async Task slowMethodAsync() 
     { 
      UpdateTxtLog("Enter in slowMethod: " + System.DateTime.Now); 
      Thread.Sleep(5000); 
      UpdateTxtLog("Exit slowMethod: " + System.DateTime.Now); 
     } 

如果我没有错,设定为“同步”(在这种情况下,单击事件),它让该方法使用的await,给点返回到执行该方法的方法它调用实​​际的方法,然后执行返回到GUI。

所以在GUI中,我单击按钮,然后在clickMethod的click事件中等待,我如何使用slowMethod等待控件返回到GUI,然后GUI不应该被阻止。但是,图形用户界面被阻止,txtLog不显示任何信息,直到slowMethod完成。

这是因为slowMethod在与GUI相同的线程中执行吗?如果我错了,使用异步通常使用与调用await方法的方法相同的线程,但我认为异步的原因可以避免这种情况。

我该如何模拟一个没有thread.Sleep的slowMethod?也许这就是问题所在,因为在slowMethod中,我睡眠线程,而slowMethod的线程与GUI相同。

这让我觉得总是推荐在其他线程中执行异步方法的代码?如果这是正确的,如果我还需要使用任务来阻止主线程,那么使用异步的意义是什么?

何时使用异步和何时使用任务?

对于这个探头,我下面这个网站的例子:http://www.codeproject.com/Articles/127291/C-5-0-vNext-New-Asynchronous-Pattern

在这个例子中,它被用来作为client.DownloadStringTaskAsync slowMethod,但对我来说,而是采用了Web客户端,我用一个虚拟的方法,用睡眠模拟slowMethod。我认为这是唯一的区别。

谢谢。 Daimroc。

回答

2

使用await TaskEx.Delay(5000)模拟等待,其执行异步睡眠/延迟。

您可能还想了解更多async/await。有几个很好的Channel9视频; Stephen Toub,Eric Lippert和许多其他微软博客都有出色的概述。 Jon Skeet的“eduasync”博客系列也非常适合真的走得更深。和其他许多人一样,我写了an async intro on my own blog

这里的asyncawait到底是如何工作,概括地说:

  • async关键字仅启用await关键字。就这些。它不是而是在后台线程上运行该方法。
  • await只有在其“awaiter”未完成时才会异步执行。

所以在你的情况下,btnAsync01_ClickslowMethodAsync都运行在UI线程上。 slowMethodAsync将同步运行(执行Thread.Sleep),然后返回到btnAsync01_Click,等待已完成的任务。由于该任务已完成,因此btnAsync01_Click只是继续执行而不会屈服于UI消息循环。

如果用await TaskEx.Delay替换Thread.Sleep,然后btnAsync01_Click将开始在UI线程上运行,并调用slowMethodAsync(也UI线程上运行)。当slowMethodAsyncawait是延迟(未完成)时,它将返回一个不完整的任务到btnAsync01_ClickbtnAsync01_Clickawait该任务(未完成),并将返回到UI循环。

当延迟到期时,它将完成,并且slowMethodAsync将恢复(在UI线程上)。当slowMethodAsync完成时,其返回的任务将完成,并且btnAsync01_Click将恢复(在UI线程上)。