异步和等待的工作原理

异步和等待的工作原理

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

问题描述

我正在尝试了解 Async 和 Await 的工作原理.如何在程序中控制行程.这是我试图理解的代码.

I am trying to understand how Async and Await works. How control travel in the program. Here is the code which I was trying to understand.

public async Task MyMethod()
{
    Task<int> longRunningTask = LongRunningOperation();
    //indeed you can do independent to the int result work here
    MySynchronousMethod();
    //and now we call await on the task
    int result = await longRunningTask;
    //use the result
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
    await Task.Delay(5000); //5 seconds delay
    return 1;
}

private void Button_Click_3(object sender, RoutedEventArgs e)
{
     MyMethod();
}

当按钮点击发生时,MyMethod() 将被调用,并从 MyMethod 中调用 LongRunningOperation() 并且需要 5 秒才能完成.所以我的问题是

When button click occur then MyMethod() will be called and from the MyMethod LongRunningOperation() will be called and it take 5 sec to complete. so my question is

  • 这一行是什么意思

  • What is the meaning of this line

Task longRunningTask = LongRunningOperation();

Task longRunningTask = LongRunningOperation();

这是做什么的int result = await longRunningTask;

可以提交上面的行,我们可以像构建一行

The above line could be committed and one line we can construct like

Task<int> longRunningTask = await LongRunningOperation();

int result = await longRunningTask;

请有人向我解释上面的代码,我不清楚.

1) 如果longRunningOperation 没有完成并且还在运行,MyMethod() 将返回到它的调用方法,因此主线程不会被阻塞.当 longRunningOperation 完成后,来自 ThreadPool 的线程(可以是任何线程)将返回到 MyMethod() 的先前状态并继续执行(在这种情况下将结果打印到控制台).

Please can someone explain to me the above code which is not clear to me.

1) if the longRunningOperation hasn't finished and is still running, MyMethod() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningOperation is done then a thread from the ThreadPool (can be any thread) will return to MyMethod() at its previous state and continue execution (in this case printing the result to the console).

第二种情况是 longRunningOperation 已经完成执行并且结果可用.当到达 await longRunningOperation 时,编译器知道它有结果并将继续在同一个线程上执行代码.(在这种情况下,将结果打印到控制台).

A second case would be that the longRunningOperation has already finished its execution and the result is available. When reaching the await longRunningOperation the compiler knows that it has the result and will keep on executing code on the very same thread. (in this case printing result to console).

第 1 点对我来说一点也不像语句如果 longRunningOperation 还没有完成并且仍在运行,MyMethod() 将返回到它的调用方法"

point 1 is not at all clear to me like the statement "if the longRunningOperation hasn't finished and is still running, MyMethod() will return to its calling method"

如果可能,请更详细地解释第一点.谢谢

if possible explain the point one in more detail. thanks

推荐答案

我有一个 async 介绍 在我的博客上,您可能会觉得有帮助.

I have an async intro on my blog that you may find helpful.

此代码:

int result = await LongRunningOperation();

本质上与此代码相同:

Task<int> resultTask = LongRunningOperation();
int result = await resultTask;

所以,是的,LongRunningOperation 是由该方法直接调用的.

So, yes, LongRunningOperation is invoked directly by that method.

await 操作符被传递一个已经完成的任务时,它会提取结果并继续执行该方法(同步).

When the await operator is passed an already-completed task, it will extract the result and continue executing the method (synchronously).

await 操作符传递一个未完成的任务(例如,LongRunningOperation 返回的任务将不会完成),则默认情况下await 将捕获当前上下文并从该方法返回一个未完成的任务.

When the await operator is passed an incomplete task (e.g., the task returned by LongRunningOperation will not be complete), then by default await will capture the current context and return an incomplete task from the method.

稍后,当 await 任务完成时,该方法的其余部分将被安排在该上下文中运行.

Later, when the await task completes, the remainder of the method is scheduled to run in that context.

这个上下文"是SynchronizationContext.Current,除非它是null,在这种情况下它是TaskScheduler.Current.如果您在控制台应用程序中运行它,则上下文通常是线程池上下文,因此 async 方法将继续在线程池线程上执行.但是,如果您在 UI 线程上执行相同的方法,则上下文是 UI 上下文,async 方法将在 UI 线程上继续执行.

This "context" is SynchronizationContext.Current unless it is null, in which case it is TaskScheduler.Current. If you're running this in a Console app, then the context is usually the thread pool context, so the async method will resume executing on a thread pool thread. However, if you execute the same method on a UI thread, then the context is a UI context and the async method will resume executing on the UI thread.

这篇关于异步和等待的工作原理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 11:36