从属性设置器调用异步方法

时间:2016-06-09 09:43:01

标签: c# asynchronous async-await

我有几个地方可以这样做,但重做代码是不可行/不切实际的。然而,似乎该方法可以被称为“正常”,例如: -

set
{
    ...
    DoSomethingAsync();
}

此行下的VS编辑器中出现一个波形,此工具提示警告: -

  

由于未等待此调用,因此在调用完成之前会继续执行当前方法。

如果没有async / await关键字,我希望该方法最终会被同步调用 。我不能来这里的是什么?

如果我将线条更改为以下内容,则波形/警告消失: -

DoSomethingAsync().Wait();

据推测,这会把它变成阻塞电话?

纯粹出于好奇,做以下事情会产生什么影响: -

Task.Run(() => DoSomethingAsync());

3 个答案:

答案 0 :(得分:5)

  

没有async / await关键字,我有点期望该方法最终会被同步调用。我不能来这里的是什么?

您的假设是错误的:async方法总是异步调用。除非你Wait(),否则它不会等到async方法完成。 Wait()确实会阻止对异步方法的调用。即使你执行Task.Run,它也会异常运行(两次,因为async方法在Task.Run内异步运行。

不能异步调用属性,因此Get方法可以解决这个问题。这样你就可以让你的代码一直异步。

答案 1 :(得分:3)

在属性设置器中调用异步方法(MVVM用法)

创建方法

DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppostreq = new HttpPost(wurl);

StringEntity se = new StringEntity(nameValuePairs.toString());
se.setContentType("application/json;charset=UTF-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=UTF-8"));

httppostreq.setEntity(se);
HttpResponse httpresponse = httpclient.execute(httppostreq);

在setter属性中调用

public class AsyncRunner
{
    public static void Run(Task task, Action<Task> onError = null)
    {
        if (onError == null)
        {
            task.ContinueWith((task1, o) => { }, TaskContinuationOptions.OnlyOnFaulted);
        }
        else
        {
            task.ContinueWith(onError, TaskContinuationOptions.OnlyOnFaulted);
        }
    }
}

这是需要运行的异步方法......

private NavigationMenuItem _selectedMenuItem;
public NavigationMenuItem SelectedMenuItem
{
    get { return _selectedMenuItem; }
    set
    {
        _selectedMenuItem = val;
        AsyncRunner.Run(YourAsyncMethod(_selectedMenuItem));            
    }
}

答案 2 :(得分:2)

如果你看一下DoSomethingAsync()的定义,它将是这样的

   public async Task<T> DoSomethingAsync()
   public       Task<T> DoSomethingAsync()

无论哪种方式,它都会返回一个(可能)刚刚开始的任务。

你可以在任务上调用.Wait(),也可以不。

如果没有,您将离开该任务以在后台运行。
这可能不是程序员的意图 - 因此警告。