【问题标题】: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 参数。

【问题讨论】:

  • 行不通。您的匿名异步函数不会将值返回给外部函数。

标签: c# windows-8 async-await


【解决方案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;
    }
    

    【讨论】:

    • 不错的,自我解决的任务并返回结果。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 2015-11-09
    • 2019-10-09
    • 2021-05-11
    • 1970-01-01
    相关资源
    最近更新 更多