首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用异步/等待是否比使用task.Start()更好?为什么?

使用异步/等待是否比使用task.Start()更好?为什么?
EN

Stack Overflow用户
提问于 2013-11-17 00:52:39
回答 3查看 4K关注 0票数 4

比较以下两种方法:

代码语言:javascript
复制
static async Task<int> DownloadAsync(string url)
{
    var client = new WebClient();
    var awaitable = client.DownloadDataTaskAsync(url);
    byte[] data = await awaitable;
    return data.Length;
}

用法:Task<int> task = DownloadAsync("http://stackoverflow.com");

代码语言:javascript
复制
static Task<int> Download(string url)
{
    var client = new WebClient();
    var task = client.DownloadDataTaskAsync(url);
    byte[] data = task.Result;
    return Task.FromResult(data.Length);
}

用法:

代码语言:javascript
复制
Task task = new Task(() => Download("http://stackoverflow.com"));
task.Start();

据我所见,这两种方法都异步运行。我的问题是:

这两种方法在行为上有什么区别吗?

为什么我们更喜欢异步等待他人,那么它是一个很好的模式?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-17 00:58:57

new Task将使用TaskScheduler.Current执行整个方法,通常使用ThreadPool

通过使用异步/等待,方法是同步输入的,并且只有在需要时才会使用异步延续。

下面的LINQPad程序可以演示我的意思:

代码语言:javascript
复制
const int delay = 1;

public async Task DoSomethingAsync()
{
    Thread.CurrentThread.ManagedThreadId.Dump();
    await Task.Delay(delay).ConfigureAwait(false);
    Thread.CurrentThread.ManagedThreadId.Dump();
}

void Main()
{
    DoSomethingAsync().Wait();  
}

尝试将delay更改为0,您将看到继续在同一个线程上继续,这是因为Task.Delay只是在没有延迟的情况下立即返回,这避免了在不需要的情况下安排和执行连续性的开销。

通过使用new Task,您将失去这一巧妙的功能,并且总是使用ThreadPool线程,即使异步方法的实现者可能不认为它是必要的。

票数 3
EN

Stack Overflow用户

发布于 2013-11-17 02:44:52

您发布的两种方法完全不同。

DownloadAsync是一种真正的异步方法。这意味着,当数据正在下载时,在该异步操作上没有阻塞的线程。

Download通过调用Task.Result来同步阻塞调用线程。我在我的博客S上解释:在一般情况下,它会导致死锁。但让我们假设没有死锁。然后从TPL任务调用它,因此它阻塞任务线程(很可能是线程池线程)。当数据正在下载时,该任务线程将在该异步操作上被阻塞。

因此,DownloadAsync更有效。

票数 7
EN

Stack Overflow用户

发布于 2013-11-17 00:58:17

看看这个帖子,Stephen准确地解释了原因和差异。

总之,这是完全一样的。这是新的和旧的等待方式。我发现异步/等待也更友好,因为其他方法中有额外的代码,并且不需要放置task.Start()。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20025858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档