再次解释异步等待 [英] Explain async await again

查看:14
本文介绍了再次解释异步等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的事件处理程序代码:

This is my event handler code:

protected async void TestrunSaveExecute()
{
    bool saveResult = await SaveTestRunAsync();
}

为了保持 UI 响应,我使用了 async/await 方法.

In order to keep the UI responsive, I used the async/await method.

据我所知,我现在可以在 SaveTestRunAsync() 中执行一些冗长的操作而不会阻塞 UI,因为它是通过使用 await 关键字解耦的.

In my understanding, I can now do some lengthy operations in SaveTestRunAsync() without blocking the UI, since it is decoupled by using the await keyword.

private async Task<bool> SaveTestRunAsync()
{
    //System.Threading.Thread.Sleep(5000); --> this blocks the UI
    await Task.Delay(5000); // this doesn't block UI

    return true;
}

你能解释一下为什么对 Thread.Sleep 的调用仍然会阻塞 UI,而 Task.Delay 不会?

Could you please explain why the call to Thread.Sleep still blocks the UI, and Task.Delay doesn't?

推荐答案

代码仍在 UI 线程上运行.

The code is still running on the UI thread.

它不在后台线程上运行.

It is not running on a background thread.

因此,您在该异步方法中执行的任何耗时、成本高昂的操作仍会在该时间段内阻塞 UI.

As such, any lengthy, costly, operation you're doing in that async method will still block the UI for that period of time.

Thread.Sleep 使 UI 线程进入睡眠状态.

Thread.Sleep puts the UI thread to sleep.

您需要了解 asyncawait 在这种情况下是如何工作的.

You need to understand how async and await works in this case.

await 这里基本上是这样说的:

await here basically says this:

让我们在这里将方法一分为二.第一部分是在 await 之前执行的任何内容.第二部分是等待对象完成后应该执行的任何内容.

Let's split the method in two here. The first portion is whatever executes up to the point of the await. The second portion is whatever should execute after the awaitable object has completed.

因此,基本上,该方法会一直执行直到到达await Task.Delay(5000);.然后它会延迟 5 秒",并说在完成后安排其余代码执行".然后它返回,以便 UI 线程可以继续发送消息.

So, basically, the method executes up until it reaches await Task.Delay(5000);. Then it puts a "delay of 5 seconds" into play, and says "schedule the rest of the code to execute when that is done". Then it returns so that the UI thread can keep pumping messages.

5 秒后,UI 线程执行该方法的其余部分.

Once the 5 seconds is up, the UI thread executes the rest of that method.

基本上,如果您执行异步 I/O,这很好,但如果您执行成本高昂的操作,例如处理大型数据集或类似操作,则效果不佳.

Basically, this is good if you do asynchronous I/O, but not so good if you do costly operations, like processing large datasets or similar.

那你怎么能做到这一点?

So how then can you do that?

您可以使用Task.Run.

这将启动另一个线程来执行给定的委托,同时 UI 线程可以自由地做其他事情.

This will spin up another thread to execute the delegate it is given, and the UI thread is free to do other stuff in the meantime.

基本上你可以把使用 await 的方法想象成这样:

Basically you can think of a method using await as this:

Life of method:    <------------------------------------------------------->
Parts:             [ start of method ----][awaitable][ rest of method -----]

所以方法会执行第一部分,直到到达await X,然后它会检查X是否已经完成,如果没有完成,它会设置一些Task 对象以这样的方式运行 awaitable 对象,一旦它完成,方法的其余部分"就会运行.

So the method will execute the first portion, until it reaches await X, then it will check if X is already done, if it's not done, it will set up some Task objects in such a way that the awaitable object gets to run, and once it has completed, the "rest of the method" gets to run.

如果 X 已经完成,也许它是一个已经完成的异步 I/O 操作,或者它完成得非常快,那么该方法将继续执行该方法的其余部分,就好像您没有编写 await 在那里.

If X was already done, perhaps it's an asynchronous I/O operation that has already completed, or it completed really fast, then the method will keep executing the rest of the method as though you hadn't written await there.

但是如果没有,那么它会返回.这很重要,因为它可以让 UI 线程(在本例中)重新发送消息,例如鼠标点击和来自用户的消息.

But if not, then it returns. This is important, because it lets the UI thread (in this case) get back to pumping messages like mouse clicks and things from the user.

一旦等待那个awaitable 对象"的任务被告知等待完成,方法的其余部分"就会被调度,这基本上(在这种情况下)将一条消息放入消息队列,要求它执行剩下的方法.

Once the task waiting for that "awaitable object" is told that the awaitable is completed, the "rest of the method" is scheduled, which basically (in this case) puts a message into the message queue asking it to execute the rest of that method.

在这样的方法中,await 语句越多,片段就越多,基本上它只会将方法分成更多部分.

The more await statements you have in such a method, the more pieces, basically it will just split the method up into more parts.

您可以使用在早期 .NET 版本中引入的 Task 类来完成所有这些工作.async/await 的全部目的是使编写代码更容易,因为将代码包装在任务对象中会导致将代码翻过来的不幸效果,并且使得处理异常和循环之类的事情变得困难.

You can do all of this with the Task class that was introduced in an earlier .NET version. The whole purpose of async / await is to make it easier to write code, since wrapping up your code in task objects had the unfortunate effect of turning your code inside out, and making it hard to handle things like exceptions and loops.

这篇关于再次解释异步等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆