我正在尝试浏览异步功能(C#.NET),并且很奇怪返回任务(即promise)的异步函数是否始终只能在异步函数中使用。编译器和文档当然会说明这一点,但我想看看我是否遗漏了一些可以解决这个问题的东西。
例如,ReturnRandomIntegerAsync(i)返回一个Task。 请注意,每5秒运行一次的while循环比花费7秒的函数更快:
void MyFunction(){
while(true)
{
i++;
var sw = Stopwatch.StartNew();
Thread.Sleep(5000);
Task<int> j = ps.ReturnRandomIntegerAsync(i);// Call to an async
// method which has a sleep for 7 seconds (and awaits for sleep to be over))
// **OUTPUT j**.
sw.Stop();
var timespan = sw.Elapsed;
Console.WriteLine("Elapsed time : " + timespan.Seconds + "\n\n");// Time taken for this iteration.
}
}
在这个例子中,我不能对ps.ReturnRandomIntegerAsync(i)进行等待,除非我使MyFunction()成为异步的。如果我不这样做,那么j就没有意义了。如果我在ps.ReturnRandomIntegerAsync(i)上执行.Result,那么它会断开异步并且经过的时间(while循环中的最后一行)显示12秒(循环中为5,方法中为7)。
如果我想在每次循环迭代中获得j的值,我在这种情况下可以想到的唯一解决方案是通过异步方法将j存储在某处(数组,集合等),然后再检索。
这是正确的方法吗?
答案 0 :(得分:2)
您当然可以存储任务,以后再await
。
Task.WhenAll
是一个常见的用例:
var task1 = SomethingAsync();
var task2 = SomethingElseAsync();
// Both operations are "in flight" at this point.
// Asynchronously wait for them both to complete.
await Task.WhenAll(task1, task2);
另一个例子是长寿命&#34;主循环&#34;任务。例如,一个不断从网络流中读取的任务。在这种情况下,你想最终&#34;加入&#34;具有能够检测异常的任务。我这样做的首选方法是await
async Task
(或者很少 - async void
)方法中的ContinueWith
任务,但您也可以使用export const myAction= () => (distaptch, getState) => {
callFunctionA(function(e){
if(e){
dispatch(eventA(e));
callFunctionB(function(e){
dispatch(eventB(e));
callFunctionC(function(e){
dispatch(eventC(e));
});
});
}
});
}
来检测这些异常。
答案 1 :(得分:2)
不,您 需要使用async
方法来使用Task
。 async
关键字只是一种语言功能,可以使异步操作更方便。在编写方法时,您可以在Task
本身(最值得注意的是ContinueWith
)上使用实际操作,然后执行此操作&#34;旧方法&#34;如果你愿意的话。
或者,可以通过编写其他Task
返回方法来完全编写某些方法,并且可能不需要自己async
。
当然,使用Task
实例编写的方法async
确实很常见。在不使用语言功能的情况下,不必要的情况并不常见,并且手动编写,几乎总是更多的工作,并没有合适的好处。