接口实现不提供异步时该怎么办

时间:2018-08-30 10:36:29

标签: c# multithreading asynchronous task

假设我有一个界面:

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的客户端应该完全知道他在做什么,否则他不能很好地控制hiw应用程序的性能。

我的界面可能具有其他Load方法。但是在这种情况下,真正的好处是什么? NotNiceDataBase的LoadAsync仍然需要一些实现。我认为抛出NotImplementedException从来都不是一个好的解决方案。

2 个答案:

答案 0 :(得分:4)

您知道async是一个实现细节,您不能在接口上定义async。所以你要做的就是

public class NotNiceDataBase : ILoader
{
    public Task<Data> LoadAsync(int id)
    {
        //this database's driver does not have aysnc methods, because it's old or done poorly.    
        var result = NotNiceDataBaseDriver.LoadData(id);
        return Task.FromResult(result);
     }
}

答案 1 :(得分:3)

只需同步运行该方法并返回已完成的任务 例如

class NotNiceDataBase : ILoader 
{
    public Task<Data> LoadAsync(int id)
    {
        var data = NotNiceDataBaseDriver.LoadData(id);
        return Task.From(data);
    }
}

您说

  

我认为NotNiceDataBase的客户端应该完全了解   他在做什么,否则他将无法控制嗨的表现   应用很好。

我不同意,如果性能是一个问题, 如果他们已经确定这是对NotNiceDataBase 然后,他们可以对此做些事情。

阐述

担心客户端如何使用界面的时间几乎可以肯定是 1 ,这不是浪费时间,不是“过早优化”事件,而是对其他人的生存焦虑未知的优化需求。

1 除非您是自己的客户,否则可能是浪费的时间。