首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Task.FromResult()与Task.Run()

Task.FromResult()与Task.Run()
EN

Stack Overflow用户
提问于 2015-12-01 02:24:54
回答 2查看 25.9K关注 0票数 31

我最近遇到了相当多的情况,其中async方法同步执行,但无论如何都会返回一个任务,所以它们可以等待,例如

代码语言:javascript
复制
public virtual Task CreateAsync(TUser user)
{
    ThrowIfDisposed();
    if (user == null) throw new ArgumentNullException("user");
    Context.Save(user);
    Context.Flush();
    return Task.FromResult(0);
}

当然,最好是将可能长时间运行的操作分派给一个线程,并返回仍处于活动状态的任务,以便真正等待:

代码语言:javascript
复制
public virtual Task CreateAsync(TUser user)
{
    ThrowIfDisposed();
    if (user == null) throw new ArgumentNullException("user");
    return Task.Run(() =>
    {
        Context.Save(user);
        Context.Flush();
    });
}

不过,我怀疑仅仅剥离TPL线程并不是最安全的做法。对这两种不同的模式有什么评论吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-01 02:28:26

如果您的方法是同步的,那么一开始就不应该返回Task。只需创建一个传统的同步方法。

如果由于某些原因这是不可能的(例如,您实现了一些异步接口),则使用Task.FromResult返回完成的任务,甚至更好,在这种情况下,Task.CompletedTask (在.NET 4.6中添加)比在实现中使用Task.Run好得多:

代码语言:javascript
复制
public virtual Task CreateAsync(TUser user)
{
    // ...
    return Task.CompletedTask;
}

如果你的应用程序接口的使用者非常关心Task-returning方法的不同步运行,他们可以自己使用Task.Run来确认。

您应该记住,异步方法可能有相当大的同步部分(第一个等待之前的部分),即使它们最终确实以异步方式继续。你不能假设异步方法会立即返回一个 Task

票数 28
EN

Stack Overflow用户

发布于 2015-12-01 02:37:53

Task.FromResult实际上并不创建或运行任务,但它只是将返回的结果包装在一个任务对象中。我个人在Unit Tests中使用了它,在那里我需要模拟Async方法,当然我也不想在单元测试中运行实际的任务。

此外,Task.Run实际上会在TaskScheduler上创建并运行一个任务。在进行Async编程时,不建议使用Task.Run。而是在任务上使用await。看斯蒂芬·克利里写的“do's and don't of Tasks很少”。

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

https://stackoverflow.com/questions/34005397

复制
相关文章

相似问题

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