C# 异步等待流

C# 异步等待流,c#,asynchronous,C#,Asynchronous,如果我做对了,只是确认一下,因为我找不到一个明确的答案: private async void button_click() { await DoWork(); Textbox.Text = "Hello World"; } private async void button_click() { var ret = await DoWork(); Textbox.Text = "Hello World"; } private async Task<i

如果我做对了,只是确认一下,因为我找不到一个明确的答案:

private async void button_click()
{
    await DoWork();

    Textbox.Text = "Hello World";
}

private async void button_click()
{
    var ret = await DoWork();

    Textbox.Text = "Hello World";
}

private async Task<int> DoWork()
{
     int ret = 0;

     ret = await WriteToDiskAsync();

     return ret;
}
private async void按钮\u click()
{
等待嫁妆();
Textbox.Text=“你好世界”;
}
专用异步无效按钮\u单击()
{
var ret=等待工作();
Textbox.Text=“你好世界”;
}
专用异步任务DoWork()
{
int-ret=0;
ret=等待WriteToDiskAsync();
返回ret;
}
如果我将async方法的返回值赋给变量,我100%确定Textbox.Text赋值是在
DoWork()
完成后完成的,,即使下面的操作没有使用ret变量。在第一个示例中,不确定Textbox.Text赋值是否在
DoWork()
完成后完成,因为UI线程未挂起且流继续,因此根据
DoWork()
和调度程序的工作量,可能会发生任何事情

我以为wait在自然语言中的意思是……wait,但不是那样的。

@两个示例处理程序中的Alberto文本仅在 do work任务完成(您也可以只使用任务而不使用 int部分,如果您不想返回任何东西,但能够等待 (方法)

但是,如果您的方法:

private async Task<int> DoWork()
{
     //Unknown code
}

如果我将async方法的返回值赋给一个变量,我100%确定Textbox.Text赋值是在DoWork()完成后完成的,即使下面的操作没有使用ret变量。在第一个示例中,不确定Textbox.Text赋值是否在DoWork()完成后完成,因为UI线程未挂起且流仍在继续,因此根据DoWork()和调度程序的工作量,任何情况都可能发生


分配与控制流无关。
await
是“产生”线程的方法,在这两种情况下,
async
方法仅在
DoWork
完成后才继续执行。(从技术上讲,在这两种情况下,
async
方法只有在从
DoWork
返回的任务完成后才继续执行)。

如果您有
async void
waitable,则不等待它。这两种方法等效。还有可能,它们产生相同的IL,因为您不使用
ret
@Alberto,我的意思是
async void
中的
async void按钮单击()。更多,还有。@ieagle请回答第一个问题。我是否100%确定在第二个示例中,文本框赋值是在
DoWork()
完成后完成的?@Alberto code after
await
仅在等待的操作完成后执行。我想保持简单,但
DoWork()中当然有一个长时间的异步操作
方法。我用写磁盘的方式改变了它。请更新您的答案,您是说在两个版本中,文本框都是在
DoWork()
完成后100%确定完成作业,对吗?你确定100%?@Alberto啊,我明白了,但即使是这样,它也应该以同样的方式运行,只是阻塞ui并等待操作完成。如果可能,请在等待长时间操作时粘贴行,有时在使用多个异步操作时可能需要使用括号。有大量代码我无法粘贴所有堆栈,
await writetodiskancy()是等效的。我编辑它是因为我真的在使用返回值。也许在你的方法的更深处,你有“ieagle”建议的异步void方法,它启动了一个没有等待的长操作,你有嵌套的异步方法吗?@Alberto可能试着调试代码->用wait在长操作结束时放置一个长延迟,然后在调用DoWork()的位置放置一个断点;到达后按step over,查看Textbox.Text=“Hello World”;是在道工完成之前执行的(如果你需要驱魔师的话:)。好吧,就像我想的那样,就像佩瑟拉尔在他的第一个评论中说的那样。但我仍然不相信这在现实中是可以保证的,有那么多事情在幕后进行,那么多线程我们无法控制…@阿尔贝托:任务只完成一次,完成后,他们会安排所有的继续
await
async
方法分解为多个“块”——每个
await
都是一个“块”。当您等待任务时(假设任务尚未完成),
await
操作符仅将下一个“块”作为该任务的延续。所以保证这一点其实很简单。异步方法的实现方式、线程数量或运行位置(UI/threadpool)无关紧要。当该任务完成时,该方法将继续,因为它是该任务的延续。
private async Task DoWork()
{
     //awaits 1 millisecond to trick the method to be really asynchronous
     await Task.Delay(1);
}