什么时候使用Task.Run浪费或妄想?

时间:2015-01-13 16:25:10

标签: c# asynchronous async-await

我有一个读取/写入对象到存储的接口。在一种情况下,存储是具有异步方法的数据库。在另一种情况下,它只是一个cookie。

我认为它建议在异步调用结束时沿着路径使用异步,因此看起来对于异步也是有意义的。但是在Cookie的情况下,我只是设置几个字段并将其粘贴在响应中,因此还没有任何异步。我可以在等待Task.Run()来匹配新界面,但我不知道这是否可取或是否对性能有负面影响。

怎么办?

public interface IProfileStore
{
    async Task SetProfile(UserProfile profile);
}

public async Task SetProfile(UserProfile profile)
{
    // Look mom, I'm needlessly async
    await Task.Run(() =>
    {
        var cookie = new HttpCookie(AnonymousCookieName);
        cookie["name"] = profile.FullName;
        HttpContext.Current.Response.Cookies.Add(cookie);
    });
}

3 个答案:

答案 0 :(得分:5)

你不应该这样做;你只是在创造不必要的线程池流失。

相反,请从方法中删除async关键字,然后只需return Task.FromResult(0)即可返回同步完成的任务

答案 1 :(得分:1)

如果你正在执行一个非常短暂的快速完成的操作,那么你很可能没有必要使用Task.Run将工作推送到另一个线程。在线程池中调度代码的行为可能需要比执行更长的时间。

至于如何做到这一点,只需删除你不需要的await Task.Run,瞧,你已经完成所有设置。您有一个仍然包含在Task中的同步操作,因此仍然匹配所需的接口。

答案 2 :(得分:1)

几乎正如SLaks所说,如果您正在做异步但返回任务,那么:

public Task SetProfile(UserProfile profile)
{
    return Task.Run(() =>
    {
        var cookie = new HttpCookie(AnonymousCookieName);
        cookie["name"] = profile.FullName;
        HttpContext.Current.Response.Cookies.Add(cookie);
    });
}

然而,正如他在这种情况下建议的那样:

public Task SetProfile(UserProfile profile)
{
    var cookie = new HttpCookie(AnonymousCookieName);
    cookie["name"] = profile.FullName;
    HttpContext.Current.Response.Cookies.Add(cookie);
    return Task.FromResult(null);
}

返回null,因为系统缓存已完成的任务。