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

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

问题描述

这是我的事件处理程序code:

 保护异步无效TestrunSaveExecute()
{
    布尔saveResult =等待SaveTestRunAsync();
}
 

为了保持用户界面响应,我使用了异步 / 等待方法。

在我的理解,我现在可以做的有些冗长的操作SaveTestRunAsync()不阻塞UI,因为它是通过使用分离了等待关键字。

 专用异步任务<布尔> SaveTestRunAsync()
{
    //System.Threading.Thread.Sleep(5000); - >此块的UI
    等待Task.Delay(5000); //这不会阻止用户界面

    返回true;
}
 

能否请您解释一下为什么在调用 Thread.sleep代码仍然让用户界面和 Task.Delay 不?

解决方案

在code是UI线程仍在运行。

这不是在后台线程上运行。

因此​​,任何冗长,成本高,操作你做的是异步方法仍然会阻止用户界面的那段时间。

Thread.sleep代码放UI线程睡眠。

您需要了解如何异步等待工作在这种情况下。

计谋这里主要说的:

  

让我们两个在这里分裂法。第一部分是什么来的计谋点执行了。第二部分是任何应该执行awaitable对象完成后<​​/ P>

因此​​,基本上,该方法执行,直到达到等待Task.Delay(5000); 。然后,它把一个5秒延时发挥作用,并说:计划的code,其余执行时做到这一点。然后返回,使UI线程可以继续抽水消息。

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

基本上,如果你做的异步I / O,但如果这样做代价高昂的操作,例如处理大型数据集或不太好相似。

这是很好的

那么,如何才能这样做呢?

您可以使用 Task.Run

这将旋转起来另一个线程来执行它被赋予了代表,并在UI线程可以自由地做其他的东西在其间。

基本上你能想到的方法使用等待,如下:

 生活的方法:其中,-------------------------------- -----------------------&GT;
配件:[法开始----] [awaitable] [休息方法-----]
 

所以,该方法将执行第一部分,直到它到达等待X ,然后它会检查如果X已经完成,如果它不这样做,它会成立以这样的方式有些工作对象的 awaitable 对象获取运行,一旦完成后,休息该方法的获取运行

若X中已经完成了,也许这是一个已经完成的异步I / O操作,或者完成真快,则该方法将继续执行该方法的其余部分,就好像你还没有写出等待那里。

但如果不是,则它返回。这一点很重要,因为它可以让UI线程(在这种情况下)回到从用户抽象鼠标点击和事物的消息。

在任务等待该awaitable对象被告知awaitable完成后,休息的方法的是预定的,这基本上(在这种情况下)将消息放入消息队列要求它执行该休息的方法。

等待你有这样的方法声明中,多件,基本上它只会分裂法成多个部分。

您可以做到这一切与工作类是在较早的.NET版本推出。对全部目的异步 / 等待是使它更易于编写code,因为结束了你的code。在任务对象已经转向内而外的code,并使其难以处理之类的异常和循环的不幸影响。

This is my event handler code:

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

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

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;
}

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

解决方案

The code is still running on the UI thread.

It is not running on a background thread.

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 puts the UI thread to sleep.

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

await here basically says this:

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.

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.

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

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?

You can use Task.Run.

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.

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

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

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.

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.

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.

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.

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

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天全站免登陆