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 afterawait
仅在等待的操作完成后执行。我想保持简单,但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);
}