抽象类中的同步或异步方法

Geo*_*ung 2 .net c# async-await

我认为使用以下abstract class作为数据库迁移的基础:

using System.Threading.Tasks;

public abstract class MigrationBase
{
    public abstract string Name { get; }
    public abstract string Description { get; }
    public abstract int FromVersion { get; }
    public abstract int ToVersion { get; }
    public abstract void Apply();
    public abstract Task ApplyAsync();
}
Run Code Online (Sandbox Code Playgroud)

现在,根据底层数据库系统,将编写具体的迁移,实现void ApplyTask ApplyAsync方法可能更有意义.我看到以下选项:

  1. 如果我决定只使用其中一种抽象方法,我强迫开发人员实现具体的迁移,以"在50%的情况下" 的一种一种方式做错.
  2. 如果我决定使用两种抽象方法,那么只要数据库系统不提供这两种可能性,我就强迫他做错了.
  3. 有一个MigrationBase,SyncMigrationBase并且AsyncMigrationBase使用类型转换处处似乎没有合理的给我.
  4. 我目前缺少一个更好的选择吗?

现在您可能会说我可以选择选项二,因为ADO.Net提供同步和异步方法,在大多数情况下,数据库适配器将提供两种变体.如果您在没有ADO.Net的情况下查看更一般的问题,是否有更好的解决方案?
如果我选择了第二选项,我是否应该提供Task ApplyAsync类似于微软所做的预先实现的版本,System.IO.Stream.ReadAsync同时考虑到Stephen Toub编写的内容?如果是的话,我还应该注意什么?

das*_*ght 7

ApplyAsync单独使用,并删除其他方法.

如果我决定只使用两种抽象方法中的一种,我强迫开发人员实现具体的迁移,以一种方式或另一种方式做错

如果用户需要async从接口或抽象类实现方法,但他必须同步完成所有操作,则使用同步方法替换async返回a 的方法绝对没有问题,该方法返回Task从result构造的已完成任务.

另一方面,您的代码始终执行调用,就像它们是异步的一样.

如果我决定使用两种抽象方法,那么只要数据库系统不提供这两种可能性,我就强迫他做错了.

没错,暴露这两种方法是一种更糟糕的选择.

有一个MigrationBase,SyncMigrationBase并且AsyncMigrationBase使用类型转换处处似乎没有合理的给我.

我认为你是对的,为可以"折叠"到基类中的内容添加一个子类确实看起来比需要更多的努力.