Pro*_*ofK 18 c# multithreading asynchronous task-parallel-library async-await
我最近遇到过很多async方法,其中方法同步执行,但无论如何都返回一个Task,因此可以等待它们,例如
public virtual Task CreateAsync(TUser user)
{
ThrowIfDisposed();
if (user == null) throw new ArgumentNullException("user");
Context.Save(user);
Context.Flush();
return Task.FromResult(0);
}
Run Code Online (Sandbox Code Playgroud)
当然最好将可能长时间运行的操作分派给一个线程并返回仍处于活动状态的任务,以便真正等待:
public virtual Task CreateAsync(TUser user)
{
ThrowIfDisposed();
if (user == null) throw new ArgumentNullException("user");
return Task.Run(() =>
{
Context.Save(user);
Context.Flush();
});
}
Run Code Online (Sandbox Code Playgroud)
不过,我有点怀疑,只是脱掉TPL线程并不是最安全的做法.有关这两种不同模式的评论吗?
i3a*_*non 16
如果您的方法是同步的,则不应该返回a Task开头.只需创建一个传统的同步方法.
如果由于某种原因不可能(例如,你实现一些异步接口)Task.FromResult在这种情况下使用甚至更好地返回已完成的任务Task.CompletedTask(在.NET 4.6中添加)比Task.Run在实现中使用要好得多:
public virtual Task CreateAsync(TUser user)
{
// ...
return Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
如果您的API的消费者非常关心Task不同步运行的返回方法,他们可以使用Task.Run它们来确保.
您应该记住,异步方法可能具有相当大的同步部分(第一个等待之前的部分),即使它们最终异步地继续.您不能假设异步方法Task无论如何都会立即返回.
Task.FromResult实际上并不创建或运行任务,但它只是将返回的结果包装在任务对象中.我个人Unit Tests在我需要模拟Async方法的地方使用它,当然我不想在单元测试中运行实际任务.
此外,Task.Run实际上会创建一个任务并在TaskScheduler上运行任务.Task.Run在进行Async编程时不建议使用它.而是用于await任务.请参阅斯蒂芬克莱里的" 做什么"和"不做任务".