是否可以在非异步方法中调用等待方法? [复制]

Posted

技术标签:

【中文标题】是否可以在非异步方法中调用等待方法? [复制]【英文标题】:Is it possible to call an awaitable method in a non async method? [duplicate] 【发布时间】:2012-09-06 07:54:41 【问题描述】:

在 C#/XAML 中的 Windows 8 应用程序中,我有时想从非异步方法调用可等待的方法。

其实替换这个是正确的:

  public async Task<string> MyCallingMethod()
  
      string result = await myMethodAsync();
      return result;
  

通过这个:

   public string MyCallingMethod()
   
       Task.Run(async () => 
            string result = await myMethodAsync();
            return result;
             );
   

对我来说的好处是我可以在没有 await 的情况下使用 MyCallingMethod,但这是正确的吗? 如果我想为 MyCallingMethod 传递 ref 参数,这可能是一个优势,因为异步方法中不可能有 ref 参数。

【问题讨论】:

行不通。您的匿名异步函数不会将值返回给外部函数。 【参考方案1】:

在非异步方法中,您可以异步启动任务而不等待结果:

public void MyCallingMethod()

    Task t = myMethodAsync();

或者您可以附加ContinueWith事件处理程序,在完成任务后调用,

public void MyCallingMethod()

    myMethodAsync().ContinueWith(
        result =>
        
            // do stuff with the result
        );

或者你可以同步从Task中获取结果:

public string MyCallingMethod()

    string result = myMethodAsync().Result;
    return result;

【讨论】:

【参考方案2】:

如果你在 UI 线程上,你真的不应该尝试做类似的事情,因为这意味着你会阻塞线程。您应该改用 ref 参数,例如通过接受包含您要更改的值的简单类类型的参数。

不这样做的另一个原因是它仍然不允许您使用ref 参数,因为lambdas 无法访问封闭方法的ref 参数。

但如果你真的想这样做(我真的认为你不应该这样做),那么你需要得到Task 的结果。比如:

public string MyCallingMethod()

    var task = Task.Run(async () =>
    
        return await myMethodAsync();
    );
    return task.Result;

【讨论】:

不错的,自我解决的任务并返回结果。谢谢

以上是关于是否可以在非异步方法中调用等待方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

等待最后一个异步调用和返回它有区别吗? [复制]

传递异步方法真的需要等待/异步模式吗? [复制]

使单元测试等待另一个方法中的异步调用

如何使用回调在任何函数中调用异步等待方法

如何在.NET中调用异步函数而不等待它[重复]

我们可以从构造函数中调用异步方法吗? [复制]