在.NET Standard库中,同步方法复用异步流程实现是否合理?
.NET Standard类库双版本方法的实现选型
开发背景
- 正在开发.NET Standard类库,要求为每个方法同时提供常规同步版本与异步版本,典型方法签名示例:
public static int DoSomethingOne(string value) { ... } public static async Task<int> DoSomethingOneAsync(string value) { ... } - 所有方法的执行逻辑包括两部分:纯字符串处理、通过EF调用数据库。
当前实现现状
- 目前维护两套完全独立的实现流程,与异步无关的通用字符串处理逻辑已经抽取为共享方法,但仍存在代码重复:比如对共享方法的调用编排、少量零散的流程控制逻辑。
- 参考到的优化方案:将内部逻辑合并,同步方法通过分支判断走异步流程,最终用
.GetAwaiter().GetResult()获取执行结果,以此减少重复代码,符合DRY原则。 - 核心疑问:这种合并结构是否可行,还是应当坚持维护独立的两套实现流程?
两套实现的代码示例
1. 现有独立实现版本
public static int DoSomethingOne(string value) { return DoSomethingOneInternal(value); } public static async Task<int> DoSomethingOneAsync(string value, CancellationToken cancellationToken) { return await DoSomethingOneInternalAsync(value, cancellationToken).ConfigureAwait(false); } private static int DoSomethingOneInternal(string value) { var input = DoStringChangeOne(value); CallDbOne(input); var output = DoStringChangeTwo(input); var count = CallDbTwo(output); return count; } private static async Task<int> DoSomethingOneInternalAsync(string value, CancellationToken cancellationToken) { var input = DoStringChangeOne(value); await CallDbOneAsync(input).ConfigureAwait(false); var output = DoStringChangeTwo(input); var count = await CallDbTwoAsync(output).ConfigureAwait(false); return count; }
2. 可选的合并实现版本
public static int DoSomethingOne(string value) { return DoSomethingOneInternalAsync(value, null, isAsync: false).GetAwaiter().GetResult(); } public static async Task<int> DoSomethingOneAsync(string value, CancellationToken cancellationToken) { return await DoSomethingOneInternalAsync(value, cancellationToken, isAsync: true).ConfigureAwait(false); } private static async Task<int> DoSomethingOneInternalAsync(string s, CancellationToken? cancellationToken, bool isAsync) { var input = DoStringChangeOne(value); if (isAsync) { await CallDbOneAsync(input).ConfigureAwait(false); } else { CallDbOne(input); } var output = DoStringChangeTwo(input); var count = isAsync ? await CallDbTwoAsync(output).ConfigureAwait(false) : CallDbTwo(output); return count; }
实际场景约束
- 目前需要适配的这类方法共10个左右,内部子方法的调用深度为2-4层,需要保证代码结构清晰可维护。
- 异步版本是使用频率更高的核心实现,有独立的高频调用流程;同步版本使用频率较低,合并方案中计划让同步版本直接转发到主异步流程完成执行。
内容的提问来源于stack exchange,提问作者borisdj
相关产品推荐
相关产品推荐

