我有一个读取/写入对象到存储的接口。在一种情况下,存储是具有异步方法的数据库。在另一种情况下,它只是一个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);
});
}
答案 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,因为系统缓存已完成的任务。