在 .net 中的可等待函数中等待

awaiting inside an awaitable function in .net

我有一个函数return是一个任务

    class Sample
    {
       TaskCompletionSource<int> _tcs;
    ..
       public Task<int> DoIt(){
         StartDoingStuff();
         return _tcs.Task;
       }
      ..
    
      private void FinshedStuffCallBack(){
        _tsc.SetResult(42);
      }
    }

来电者去

 var sample = new Sample();
  var result = await Sample.DoIt();

工作正常

现在我需要在DoIt中做一些额外的事情,这本身就是可等待的

我天真地试过了

       public async Task<int> DoIt(){
        
         await DoOtherAsyncStuff();
          StartDoingStuff();
         return _tcs.Task;
       }

但这是不允许的

CS4016 Since this is an async method, the return expression must be of type 'int' rather than 'Task'

好的,我明白它想说什么,但这不是我的意图,我还没有 return 值,一旦 StartDoingStuff 触发回调就会出现。

不确定接下来要尝试什么。

您很可能只需要(注意最后一行的 await):

       public async Task<int> DoIt()
       {
           await DoOtherAsyncStuff();
           StartDoingStuff();
           return await _tcs.Task;
       }
最后一行需要

await,因为 async 函数 returning Task<int> 需要 return int,而 _tcs.TaskTask<int>。使用 await 将等待任务完成,使用 return int 这是我们需要的。

但是,根据您的完整代码,您可能还需要其他东西。例如,如果您使用 TaskCompletionSource 做更复杂的事情,您可能需要删除此定义的 async 并执行类似

的操作
       public Task<int> DoIt()
       {
           return DoOtherAsyncStuff().ContinueWith(_ => 
               {
                   StartDoingStuff();
                   return _tcs.Task;
               }, TaskCompletionOptions.ExecuteSynchronously);
       }

一般来说,最好不要乱用 TaskCompletionSource,除非您正在做更高级的事情,例如提供基于 synchronous/callback 的东西的异步抽象。因此,完整的代码示例可能会改变我的答案(例如 StartDoingStuff + DoOtherAsyncStuff 的主体是什么?)。