Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
476 views
in Technique[技术] by (71.8m points)

c# - 如何以及何时使用“异步”和“等待”(How and when to use ‘async’ and ‘await’)

From my understanding one of the main things that async and await do is to make code easy to write and read - but is using them equal to spawning background threads to perform long duration logic?

(根据我的理解, asyncawait要做的主要事情之一就是使代码易于编写和读取-但是使用它们是否等于生成后台线程来执行长时间逻辑?)

I'm currently trying out the most basic example.

(我目前正在尝试最基本的示例。)

I've added some comments inline.

(我在行中添加了一些评论。)

Can you clarify it for me?

(你能为我澄清一下吗?)

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 
}

async Task<int> DoSomethingAsync()
{
    // is this executed on a background thread?
    System.Threading.Thread.Sleep(5000);
    return 1;
}
  ask by Dan Dinu translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When using async and await the compiler generates a state machine in the background.

(使用asyncawait ,编译器会在后台生成状态机。)

Here's an example on which I hope I can explain some of the high-level details that are going on:

(这是一个例子,我希望我可以解释正在发生的一些高级细节:)

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); // 1 second delay
    return 1;
}

OK, so what happens here:

(好,那么这里发生了什么:)

  1. Task<int> longRunningTask = LongRunningOperationAsync(); starts executing LongRunningOperation

    (开始执行LongRunningOperation)

  2. Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.

    (假设主线程(线程ID = 1)完成独立工作,然后await longRunningTask到达。)

    Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked.

    (现在,如果longRunningTask尚未完成并且仍在运行,则MyMethodAsync()将返回其调用方法,因此主线程不会被阻塞。)

    When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).

    (当longRunningTask完成时,来自ThreadPool的线程(可以是任何线程)将在其先前的上下文中返回MyMethodAsync()并继续执行(在这种情况下,将结果打印到控制台)。)

A second case would be that the longRunningTask has already finished its execution and the result is available.

(第二种情况是longRunningTask已经完成其执行并且结果可用。)

When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread.

(当到达await longRunningTask我们已经有了结果,因此代码将继续在同一线程上执行。)

(in this case printing result to console).

((在这种情况下,将结果打印到控制台)。)

Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.

(当然,对于上面的示例,情况并非如此,其中涉及Task.Delay(1000) 。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...