使用async/await时,GUI会冻结

use*_*580 3 c# wpf async-await

我想弄清楚下面的代码有什么问题.我认为使用async和await让我忘记了诸如冻结之类的GUI问题,因为一些长代码阻塞了主线程.

单击按钮后,GUI响应,直到调用longRunningMethod,如下所示:

 private async void openButton_Click(object sender, RoutedEventArgs e)
 {
    //doing some usual stuff before calling downloadFiles
    Task<int> result = await longRunningMethod(); // async method

    //at this point GUI becomes unresponsive

    //I'm using the result here, so I can't proceed until the longRunningMethod finishes

  }
Run Code Online (Sandbox Code Playgroud)

在方法完成之前我无法继续,因为我需要result.为什么这段代码会冻结我的应用?

Ste*_*ary 7

问题在于longRunningMethod.

代码可能正在做的是一些CPU绑定或阻塞操作.

如果要在后台线程上运行一些CPU绑定代码,则必须明确地执行此操作; async不会自动跳线程:

int result = await Task.Run(() => longRunningMethod());
Run Code Online (Sandbox Code Playgroud)

请注意,如果longRunningMethod是CPU绑定的,它应该具有同步 - 非异步 - 签名.

如果longRunningMethod没有 CPU绑定(即,它是目前拦截),那么您需要更改阻塞的方法调用中longRunningMethod是异步的,并通过调用它们await.然后你可以通过以下方式进行longRunningMethod异步调用await:

int result = await longRunningMethodAsync();
Run Code Online (Sandbox Code Playgroud)