是一个异步函数返回一个只能由异步函数使用的Task吗?

时间:2017-03-20 18:55:42

标签: c# asynchronous async-await

我正在尝试浏览异步功能(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存储在某处(数组,集合等),然后再检索。

这是正确的方法吗?

2 个答案:

答案 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方法来使用Taskasync关键字只是一种语言功能,可以使异步操作更方便。在编写方法时,您可以在Task本身(最值得注意的是ContinueWith)上使用实际操作,然后执行此操作&#34;旧方法&#34;如果你愿意的话。

或者,可以通过编写其他Task返回方法来完全编写某些方法,并且可能不需要自己async

当然,使用Task实例编写的方法async确实很常见。在不使用语言功能的情况下,不必要的情况并不常见,并且手动编写,几乎总是更多的工作,并没有合适的好处。