假设我有一个接口:
interface ILoader()
{
Task<Data> LoadAsync(int id);
}
我有两个此接口的实现:
class NiceDataBase : ILoader
{
public async Task<Data> LoadAsync(int id)
{
//this database has async way of fetching the data
return await NiceDataBaseDriver.LoadDataAsync(id);
}
}
class NotNiceDataBase : ILoader
{
public async Task<Data> LoadAsync(int id)
{
//this database's driver does not have aysnc methods, because it's old or done poorly.
return await Task.Run(() => NotNiceDataBaseDriver.LoadData(id));
}
}
NotNiceDataBase没有提供真正的异步加载数据的方式,所以我实际上在新线程中运行它,但我理解的是,这不是真正的异步,因为真正的异步不使用新线程。那么我的NotNiceDataBase实现是好的吗?它有点欺骗用户认为他正在运行一个真正的异步操作。
如何处理这种情况是最优的?我认为NotNiceDataBase的客户端应该完全知道自己在做什么,否则他将无法很好地控制应用程序的性能。
我的界面可以有额外的Load方法。但在这种情况下,真正的好处是什么?仍然需要一些NotNiceDataBase的LoadAsync实现。我认为抛出NotImplementedException永远都不是一个好的解决方案。
NotNiceDatabase
实现添加注释或修改接口以提供非异步的Data Load(int id)
。 - IronAcesNiceDataBase
的消费者正在使用异步方法,如果他们开始使用NotNiceDataBase
,他们将期望它能够正常工作。显然,你不能指望他们去改变自己的代码以开始使用Data Load(int id)
方法。 - Nisarg ShahNotNiceDatabase
中的LoadAsync
中删除async
和await
。合同要求您返回一个Task<Data>
。您的Task.Run
调用显然正在生成这样的项目。这里不需要添加异步机制。 - Damien_The_UnbelieverNotNiceDatabase
中,LoadAsync
不需要async
和await
,而客户端的可观察行为将会(大多数情况下)相同。那么为什么要强制编译器为该方法构建异步状态机呢?当它不需要时。 - Damien_The_Unbeliever