调用异步方法和Task.Run异步方法之间的区别 [英] Difference between calling an async method and Task.Run an async method

查看:742
本文介绍了调用异步方法和Task.Run异步方法之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的视图模型中有一个方法

I have a method in my view model

private async void SyncData(SyncMessage syncMessage)
{
    if (syncMessage.State == SyncState.SyncContacts)
    {
        this.SyncContacts(); 
    }
}

private async Task SyncContacts()
{
    foreach(var contact in this.AllContacts)
    {
       // do synchronous data analysis
    }

    // ...

    // AddContacts is an async method
    CloudInstance.AddContacts(contactsToUpload);
}

当我从UI命令调用SyncData并同步大量数据时,UI冻结.但是当我用这种方法呼叫SyncContacts

When I call SyncData from the UI commands and I'm syncing a large chunk of data UI freezes. But when I call SyncContacts with this approach

private void SyncData(SyncMessage syncMessage)
{
    if (syncMessage.State == SyncState.SyncContacts)
    {
        Task.Run(() => this.SyncContacts()); 
    }
}

一切都很好.他们不应该一样吗? 我当时在想,不使用await来调用异步方法会创建一个新线程.

Everything is fine. Should not they be the same? I was thinking that not using await for calling an async method creates a new thread.

推荐答案

它们不一样吗?我当时以为不用等待 调用异步方法会创建一个新线程.

Should not they be the same? I was thinking that not using await for calling an async method creates a new thread.

否,async不会神奇地为其方法调用分配新线程. async-await主要是关于利用自然异步API的优势,例如对数据库的网络调用或远程Web服务.

No, async does not magically allocate a new thread for it's method invocation. async-await is mainly about taking advantage of naturally asynchronous APIs, such as a network call to a database or a remote web-service.

使用Task.Run时,显式使用线程池线程执行委托.如果您使用async关键字标记方法,但在内部没有await任何内容,它将同步执行.

When you use Task.Run, you explicitly use a thread-pool thread to execute your delegate. If you mark a method with the async keyword, but don't await anything internally, it will execute synchronously.

我不确定您的SyncContacts()方法实际上是做什么的(因为您没有提供它的实现),但是将其标记为async本身将不会给您带来任何好处.

I'm not sure what your SyncContacts() method actually does (since you haven't provided it's implementation), but marking it async by itself will gain you nothing.

现在您已经添加了实现,我看到两件事:

Now that you've added the implementation, i see two things:

  1. 我不确定您的同步数据分析需要占用多少CPU,但是对于UI而言,足以使其变得无响应.
  2. 您没有在等待异步操作.它需要看起来像这样:

  1. I'm not sure how CPU intensive is your synchronous data analysis, but it may be enough for the UI to get unresponsive.
  2. You're not awaiting your asynchronous operation. It needs to look like this:

private async Task SyncDataAsync(SyncMessage syncMessage)
{
    if (syncMessage.State == SyncState.SyncContacts)
    {
        await this.SyncContactsAsync(); 
    }
}

private Task SyncContactsAsync()
{
    foreach(var contact in this.AllContacts)
    {
       // do synchronous data analysis
    }

    // ...

    // AddContacts is an async method
    return CloudInstance.AddContactsAsync(contactsToUpload);
}

这篇关于调用异步方法和Task.Run异步方法之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆