嵌套并继承异步/任务

时间:2016-10-19 22:17:02

标签: c# .net async-await cross-platform

我正在开发一个具有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类型有什么好处吗?大概应用程序调用{​​{1}},那么为什么让适配器为await MyFileProcessor.DoSomeWorkAsync(...)
  • 这些操作主要是I / O绑定,而不是CPU绑定 - 这是否会影响我决定如何设计这些组件?

我知道很难在一个简单的例子中捕捉到核心问题,所以我很抱歉,如果我给出的例子太过微不足道,我的问题就不清楚了。

加分问题:如果async不需要执行任何CPU绑定工作,那么使用MyFileProcessor是否有任何好处?

1 个答案:

答案 0 :(得分:1)

  

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

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

  

让IMyAdapter返回任务类型有什么好处?大概应用程序调用等待MyFileProcessor.DoSomeWorkAsync(...),那么为什么让适配器变为异步?

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

  

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

是。每当你有一个可能异步实现的接口时,它应该具有这些方法的异步兼容签名。

  

如果MyFileProcessor不需要执行任何CPU绑定工作,那么使用异步是否有任何好处?

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

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