C# 是否可以在非异步方法中调用可等待的方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12402681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:08:25  来源:igfitidea点击:

Is it possible to call an awaitable method in a non async method?

c#windows-8async-await

提问by Thomas Salandre

In a windows 8 application in C#/XAML, I sometimes want to call an awaitable method from a non asynchronous method.

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

Actually is it correct to replace this :

实际上替换这个是否正确:

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

by this :

这样 :

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

The advantage for me is that I can use MyCallingMethod without await but is this correct? This can be an advantage if I want to pass a ref parameter for MyCallingMethod since It is not possible to have ref parameters in an async method.

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

回答by svick

You really shouldn't try to do something like that if you're on the UI thread, because that will mean you will block the thread. You should instead work around the refparameter, for example by accepting a parameter of a simple class type, that contains the value you want to change.

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

Another reason why not to do this is that it still won't let you use refparameters, because lambdas can't access refparameters of the enclosing method.

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

But if you really want to do this (again, I really think you shouldn't), then you will need to get the result of the Task. Something like:

但是,如果您真的想这样做(同样,我真的认为您不应该这样做),那么您将需要获得Task. 就像是:

public string MyCallingMethod()
{
    var task = Task.Run(async () =>
    {
        return await myMethodAsync();
    });
    return task.Result;
}

回答by Martin Suchan

In non-async method you can either start the Task asynchronously and not wait for the result:

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

public void MyCallingMethod()
{
    Task t = myMethodAsync();
}

or you can attach ContinueWith event handler, which is called after finishing the Task,

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

public void MyCallingMethod()
{
    myMethodAsync().ContinueWith(
        result =>
        {
            // do stuff with the result
        });
}

or you can get the result from the Task synchronously:

或者您可以同步从任务中获取结果:

public string MyCallingMethod()
{
    string result = myMethodAsync().Result;
    return result;
}