嵌套和继承async/Tasks

本文关键字:Tasks async 继承 嵌套 | 更新日期: 2023-09-27 18:13:57

我正在开发一个具有async API的PCL(我是本主题的新手(。从我在网上做的研究来看,我对行为和设计含义感到困惑。假设应用程序消耗了一些入口点API,它封装了一些抽象的底层来访问文件。假设此代码正在客户端运行。

public interface IFileProcessor
{
    Task ProcessFile(string filename);
}
public class MyFileProcessor : IFileProcessor
{
    // Adapter can be SomeAdapter or SomeOtherAdapter
    private IMyAdapter _adapter;
    public Task ProcessFile(string filename)
    {
        File file = await _adapter.GetFileAsync(filename).ConfigureAwait(false);
        // Some CPU bound operation
        DoSomeWorkOnFile(file);
        await _adapter.SaveAsync(file);
    }
    private void DoSomeWorkOnFile(File file)
    {
        // do some CPU heavy work here
    }
}
internal interface IMyAdapter
{
    Task<File> GetFileAsync(string filename);
    Task SaveAsync(File file);
}
// Some adapter for a client that has an async API and is mainly I/O bound
internal class SomeAdapter : IMyAdapter
{
    private SomeClient _client;
    public async Task<File> GetFileAsync(string filename)
    {
        // Fetch from server or something
        return await _client.SearchForFileAsync(filename).ConfigureAwait(false);
    }
    public async Task SaveAsync(File file)
    {
        // Push to server or something
        await _client.SaveFileAsync(file).ConfigureAwait(false);
    }
}

但是假设我有另一个适配器,它没有async API,并且它的操作正在阻塞:

// Some adapter for a client that has no async API and is mainly I/O bound
internal class SomeOtherAdapter : IMyAdapter
{
    private SomeOtherClient _client;
    // Don't declare as async since it can't await?
    public Task<File> GetFileAsync(string filename)
    {
        // Read from disk or something
        File file = _client.GetFile(filename);
        return Task.FromResult(file);
    }
    public Task SaveAsync(File file)
    {
        // Write to disk or something
        _client.Save(file);
    }
}
  • 尽管存在行为差异,SomeOtherAdapter是否有实现IMyAdapter的业务
  • 让IMyAdapter返回Task类型有什么好处吗?假定应用程序调用await MyFileProcessor.DoSomeWorkAsync(...),那么为什么让适配器为async
  • 这些操作主要是I/O绑定的,而不是CPU绑定的——这是否会影响我设计这些组件的决策

我知道很难在一个简单的例子中抓住核心问题,所以如果我举的例子太琐碎,无法让我的问题变得清晰,我很抱歉。

额外的问题:如果MyFileProcessor不需要做任何CPU绑定的工作,那么使用async有什么好处吗?

嵌套和继承async/Tasks

SometherAdapter是否有任何业务实现IMyAdapter,尽管存在行为差异?

是的。当您处理接口时,任务返回方法表明它可能是异步的。如果您有一个真正的(即非测试存根(同步实现,我会在接口本身的文档中注意到,方法调用实际上可能是同步的。

让IMyAdapter返回Task类型有什么好处吗?假定应用程序调用等待MyFileProcessor.DSomeWorkAsync(…(,那么为什么要让适配器异步呢?

是的。您的第一个示例是使用异步I/O绑定操作,因此使接口任务返回(即异步兼容(是完全有意义的。

这些操作主要是I/O绑定的,而不是CPU绑定的——这是否会影响我设计这些组件的决策?

是的。任何时候,只要您有一个可能异步实现的接口,它就应该为这些方法提供异步兼容的签名。

如果MyFileProcessor不需要做任何CPU绑定的工作,那么使用异步有什么好处吗?

我不明白这个问题;这似乎意味着异步应该用于CPU绑定的工作。但这与async的工作方式相反;async自然适合I/O绑定的代码,而不是CPU绑定的代码。

你可能对我的async OOP系列博客感兴趣。