C# 抽象类中的同步或异步方法
我考虑使用以下C# 抽象类中的同步或异步方法,c#,.net,async-await,C#,.net,Async Await,我考虑使用以下抽象类作为数据库迁移的基础: 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 T
抽象类作为数据库迁移的基础:
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();
}
现在,根据将要编写的具体迁移的底层数据库系统,实现void Apply
或Task ApplyAsync
方法可能更有意义。我看到以下选项:
如果我决定只使用两种抽象方法中的一种,我会强制实现具体迁移的开发人员以或的方式“在50%的情况下”错误地进行迁移
如果我决定同时使用这两种抽象方法,只要数据库系统不能同时提供这两种可能性,我就会强迫他做错事
拥有一个MigrationBase
、SyncMigrationBase
和AsyncMigrationBase
并在任何地方使用类型转换对我来说都不合理
有没有更好的选择,我现在错过了
现在您可能会说我可以选择选项二,因为ADO.Net提供了同步和异步方法,在大多数情况下,数据库适配器将提供这两种变体。如果您不考虑ADO.Net而只考虑更一般的问题,是否有更好的解决方案?
如果我选择了选项二,我是否应该提供一个预实现版本的任务ApplyAsync
,类似于微软在System.IO.Stream.ReadAsync
中所做的,同时考虑Stephen Toub所写的内容?如果是,我还应该注意什么?单独使用ApplyAsync
,并删除其他方法
如果我决定只使用两种抽象方法中的一种,我会强制实现具体迁移的开发人员以一种或另一种方式做错事
如果用户需要从接口或抽象类实现async
方法,但他必须同步执行所有操作,那么用同步方法替换返回任务的async
方法绝对没有问题,该方法返回根据结果构造的已完成任务
另一方面,您的代码总是像执行异步调用一样执行调用
如果我决定同时使用这两种抽象方法,只要数据库系统不能同时提供这两种可能性,我就会强迫他做错事
没错,公开这两种方法是更糟糕的选择
拥有一个MigrationBase
、SyncMigrationBase
和AsyncMigrationBase
并在任何地方使用类型转换对我来说都不合理
我认为你是对的,为可以“折叠”到基类中的东西添加一个子类看起来确实比必要的更费劲。然后我需要,即bool
propertiesSupportsSync
和SupportsAsync
,这对我来说似乎也不是一个好的设计……或者,没有属性:我不认为在很多情况下使用类的主要特性会导致抛出异常,这样它就可以在try-catch块中使用,以决定将使用哪个变量。那么调用方法…Async
会不会很混乱?如果我不这样做,我会打破这个模式吗?@Georg你会打破哪个模式?您有一个名为…async的async方法,这是正确的。我会通过不调用它async来打破这种模式。但是我希望一个名为Async的方法也是真正异步的。@Georg实现该方法的类可以使其实际运行Async。如果这个实现是同步的,那么:1)代码对于这个实现来说太短了,没有人会在意它是同步的。或者2)同步实现需要异步,例如发送到线程池。@GeorgJung调用方可以使用任务调用该方法。运行,因为调用方不应该考虑方法实现的细节,除了他自己调用的方法的性能之外。从同步实现抽象类开始的程序员可能会在异步工具对其实现可用时重构代码,并为您提供真正的异步方法,只要您给他们这样做的选项。