使用异步/等待时,GUI冻结 [英] GUI freezes when using async/await
问题描述
我正在尝试找出下面的代码出了什么问题.我以为使用async和await让我忘记了诸如冻结之类的GUI问题,因为一些长代码阻塞了主线程.
I'm trying to figure out what's wrong with the code below. I thought that using async and await lets me forget about GUI issues such as freezing because some long code is blocking the main thread.
单击按钮后,GUI会响应,直到调用 longRunningMethod
,如下所示:
After I click the button, the GUI is responsive until the call to longRunningMethod
, as shown below:
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
}
在方法完成之前我无法继续,因为我需要 result
.为什么这段代码会冻结我的应用程序?
I can't proceed until the method finishes, because I need the result
. Why this code freezes my app?
推荐答案
问题出在 longRunningMethod
之内.
代码可能所执行的操作是某些CPU约束或阻塞操作.
What the code is probably doing is some CPU-bound or blocking operation.
如果要在后台线程上运行一些CPU绑定的代码,则必须显式地执行; async
不会自动跳转线程:
If you want to run some CPU-bound code on a background thread, you have to do so explicitly; async
won't jump threads automatically:
int result = await Task.Run(() => longRunningMethod());
请注意,如果 longRunningMethod
受CPU限制,则应具有同步(而非异步)签名.
Note that if longRunningMethod
is CPU-bound, it should have a synchronous - not asynchronous - signature.
如果 longRunningMethod
不是不是受CPU限制(即,它当前正在阻塞),那么您需要在 longRunningMethod
中更改阻塞方法调用异步,然后通过 await
调用它们.然后,您可以使 longRunningMethod
异步并通过 await
进行调用:
If longRunningMethod
is not CPU-bound (i.e., it's currently blocking), then you need to change the blocking method calls within longRunningMethod
to be asynchronous, and call them via await
. Then you can make longRunningMethod
asynchronous and call it via await
as well:
int result = await longRunningMethodAsync();
这篇关于使用异步/等待时,GUI冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!