0

我正在使用异步 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);
        }

如果没有错,设置一个带有“sync”的方法(这里是click事件),它让方法使用await,将执行点返回给调用实际方法的方法,然后执行返回GUI .

所以在GUI中,我点击按钮,然后在click事件中等待slowMethod,我如何将await与slowMethod一起使用,控件应该返回给GUI,然后GUI不应该被阻塞。但是,GUI 被阻止并且 txtLog 直到 slowMethod 完成才显示任何信息。

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

如何在没有 thread.Sleep 的情况下模拟 slowMethod?也许这就是问题所在,因为在 slowMethod 中我休眠了线程,而 slowMethod 的线程与 GUI 相同。

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

何时使用异步以及何时使用任务?

对于此探测,我正在关注此 Web 中的示例:http: //www.codeproject.com/Articles/127291/C-5-0-vNext-New-Asynchronous-Pattern

在这个例子中,它使用了 client.DownloadStringTaskAsync 作为 slowMethod,但在我的例子中,我没有使用 WebClient,而是使用了一个虚拟方法,通过睡眠来模拟一个 slowMethod。我认为这是独特的区别。

谢谢。戴姆洛克。

4

1 回答 1

2

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

您可能还想在async/上阅读更多内容await。有几个不错的 Channel9 视频;Stephen Toub、Eric Lippert 和许多其他 Microsoft 博主都有出色的概述。Jon Skeet 的“eduasync”博客系列也非常适合深入研究。我已经在我自己的博客上写了一个异步介绍,其他许多人也是如此。

简而言之,这是如何async以及await真正起作用的:

  • async关键字仅启用await关键字。就这些。它不在后台线程上运行该方法。
  • await仅当其“等待者”未完成时才异步执行。

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

如果替换Thread.Sleepawait TaskEx.DelaybtnAsync01_Click则将开始在 UI 线程上运行,并将调用slowMethodAsync(也在 UI 线程上运行)。当slowMethodAsync awaits 延迟(即未完成)时,它会返回一个未完成的任务给btnAsync01_ClickbtnAsync01_Clickawait执行该任务(未完成),并将返回到 UI 循环。

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

于 2012-04-07T16:59:38.500 回答