【发布时间】:2015-03-27 16:28:28
【问题描述】:
类似于Implementing an interface that requires a Task return type in synchronous code,尽管我很好奇是否应该忽略我的情况产生的编译器错误。
假设我有一个这样的界面:
public interface IAmAwesome {
Task MakeAwesomeAsync();
}
在某些实现中,使用 async 和 await 异步完成会带来惊人的好处。这确实是界面试图允许的。
在其他情况下,也许很少见,只需要一个简单的同步方法就可以了。所以让我们假设实现如下所示:
public class SimplyAwesome : IAmAwesome {
public async Task MakeAwesomeAsync() {
// Some really awesome stuff here...
}
}
这可行,但编译器发出警告:
此方法缺少“等待”运算符,将同步运行。 考虑使用
await运算符来等待非阻塞 API 调用, 或 'await TaskEx.Run(...)' 在后台执行 CPU 密集型工作 线程。
编译器实际上是在建议这个解决方案:
public class SimplyAwesome : IAmAwesome {
public async Task MakeAwesomeAsync() {
await Task.Run(() => {
// Some really awesome stuff here, but on a BACKGROUND THREAD! WOW!
});
}
}
我的问题是 - 当我选择忽略此编译器警告时应该确定什么?在某些情况下,工作是如此简单,以至于为它生成一个线程无疑会适得其反。
【问题讨论】:
-
你“应该”做的是拥有
public interface IAmAwesome { Task MakeAwesomeAsync(); void MakeAwesome(); },所以异步和同步方法都暴露了。但如果这对你的现实世界情况是可行的,那就另当别论了。 -
我想问题是你为什么要做不涉及任何异步的任务。你能提供一个具体的用例吗?
-
@JLRishe 一个常见的例子是做一些有时可以被缓存的事情。 “从缓存中获取”版本可以是同步的,缓存未命中版本是异步的。
-
在不过度参与的情况下,在我的例子中,示例是定价。有时它是简单的数学运算(即受 CPU 限制),有时它涉及昂贵的 API 和数据库调用。
-
我会衡量计算的成本。如果它相当快,将结果包装在
Task中应该没问题。
标签: c# multithreading asynchronous async-await task-parallel-library