当我阅读有关async
和await
的Microsoft文档时,我不明白,
异步方法旨在作为非阻塞操作。等待 异步方法中的表达式不会阻塞当前线程 等待的任务正在运行。相反,该表达式将其余部分签名 方法的延续,并将控制权返回给的调用者 异步方法。
所以请考虑我的代码:
public Form1()
{
InitializeComponent();
AsyncTest();
Test(1);
}
private async void AsyncTest()
{
HttpClient client = new HttpClient();
var ss = TT(2);
var s = await ss;
for (int i = 0; i < 10; i++)
{
//loop
}
}
private async Task<int> TT(int i)
{
while (true)
{
if (i > 1000000000)
break;
i++;
}
return i;
}
}
每当我调用AsyncTest()时,它都会等待通过 await键指定的TT方法,但是它将控制权返回给主调用者是什么意思?? 它不会返回到form1,如果TT是一个无限循环,它将永远存在。 谢谢
答案 0 :(得分:1)
在我看来,您是异步等待的新手。您违反了有关如何使用async-await的几条规则。
要使函数异步,请执行以下操作:
Task<TResult>
而不是TResult
;返回Task
而不是void
void
而不是Task
指南:让async作为异步函数的后缀。这使您可以创建执行相同操作的同步和异步功能:void MyTest()
和Task MyTestAsync()
遵循这些规则,您不能从构造函数内部调用异步函数。在使用Winforms时,您的代码可能像这样:
public Form1()
{
InitializeComponent();
}
public async void OnButton1_Clicked(object sender, ...)
{ // because this is an event handler the return value is void
// Start the first test and await until ready
await TestAsync();
// Start the second test and await until ready:
int i = await TestAsync(1);
}
如果调用异步函数,则知道该函数内部的某个地方正在等待。如果在等待内部函数时有有意义的事情要做,请不要等待。通话结束后做一些有用的事情,并在需要结果后立即等待返回的Task:
public async void OnButton2_Clicked(object sender, ...)
{
// Start a test, but don't await yet
var task1 = TestAsync(1);
// if here, function TestAsync is awaiting somewhere
// it is not finished yet, so you can't use the result of it
// But you can do Something else:
DoSomethingElse();
// if here you really need the result of TestAsync, await for it
int i = await task1;
// if here you know that TestAsync is finished, i has the proper return value
}
您不必一个个地启动并等待任务,您可以启动多个任务并在需要结果时立即等待它们:
public async void OnButton3_Clicked(object sender, ...)
{
// start several tasks. Don't await yet:
var task1 = TestAsync(1);
var task2 = TestAsync(2);
var task3 = TestAsync(3);
DoSomethingElse();
// if here I need the results of all three tasks:
var myTasks = new Task[] {task1, task2, task3};
await Task.WhenAll(myTasks);
}
this interview with Eric Lippert,确实对我帮助理解异步等待有所帮助,他将异步等待与做早餐的厨师进行了比较。如果厨师必须等待水沸腾,他不会闲着,而是四处看看是否可以做其他事情。在中间的某个地方搜索async-await。
另一篇帮助我遵循异步等待准则的文章是Async and Await by the ever so helpful Stephen Cleary