.NET客户端WCF请求队列改造优化技术问询
优化方案建议
1. 用TaskCompletionSource桥接WCF回调与异步代码
将WCF的回调机制转换为Task模型,摆脱事件驱动的繁琐实现,让代码逻辑更线性可读。通过GUID映射TaskCompletionSource,在回调触发时完成对应任务:
public class WcfRequestManager : ISomeCallback { private readonly ISomeService _someService; private readonly Dictionary<Guid, TaskCompletionSource<RequestOutcome>> _pendingRequests = new(); private readonly object _syncLock = new(); public WcfRequestManager(ISomeService someService) { _someService = someService; } public Task<RequestOutcome> SendRequestAsync(Request request) { var requestId = _someService.AddToQueue(request); var tcs = new TaskCompletionSource<RequestOutcome>(); lock (_syncLock) { _pendingRequests.Add(requestId, tcs); } return tcs.Task; } public void NotifyExecuting(Guid guid) { // 可选:记录请求执行状态,无需修改Task状态 } public void NotifyComplete(Guid guid) { lock (_syncLock) { if (_pendingRequests.TryRemove(guid, out var tcs)) { tcs.SetResult(RequestOutcome.Success); } } } public void NotifyFault(Guid guid, byte[] data) { lock (_syncLock) { if (_pendingRequests.TryRemove(guid, out var tcs)) { tcs.SetException(new RequestFailureException(data)); } } } } // 自定义结果枚举和异常类 public enum RequestOutcome { Success } public class RequestFailureException : Exception { public byte[] FaultData { get; } public RequestFailureException(byte[] data) : base("请求执行失败") => FaultData = data; }
2. 重构业务流程为异步方法
将原来的Action类改为异步流程,用await串联多个请求,替代事件回调的链式触发,逻辑更直观:
public class ProcessWorkflow { private readonly WcfRequestManager _requestManager; public ProcessWorkflow(WcfRequestManager requestManager) { _requestManager = requestManager; } public async Task ExecuteAsync() { // 执行请求X并等待完成 var xResult = await _requestManager.SendRequestAsync(new RequestX()); if (xResult != RequestOutcome.Success) throw new InvalidOperationException("Request X执行失败"); // 基于X的结果构造请求Y并执行 var yRequest = new RequestY(GetXResultData(xResult)); await _requestManager.SendRequestAsync(yRequest); // 执行请求Z await _requestManager.SendRequestAsync(new RequestZ()); } private object GetXResultData(RequestOutcome result) { // 从结果中提取业务数据 return new object(); } }
3. 异步化任务队列实现
替换原有的事件驱动队列,用异步任务串行执行逻辑,利用Task的状态管理队列流转,避免手动维护CurrentAction和事件绑定:
public class AsyncWorkflowQueue { private readonly Queue<Func<Task>> _pendingWorkflows = new(); private readonly object _syncLock = new(); private Task _currentExecutingTask = Task.CompletedTask; public void EnqueueWorkflow(Func<Task> workflowFunc) { lock (_syncLock) { _pendingWorkflows.Enqueue(workflowFunc); } _ = ProcessQueueAsync(); // 后台启动队列处理,无需阻塞调用方 } private async Task ProcessQueueAsync() { Func<Task> nextWorkflow = null; lock (_syncLock) { if (_currentExecutingTask.IsCompleted && _pendingWorkflows.Count > 0) { nextWorkflow = _pendingWorkflows.Dequeue(); _currentExecutingTask = nextWorkflow(); } } if (nextWorkflow != null) { try { await _currentExecutingTask; } catch (Exception ex) { // 记录异常日志,根据业务需求决定是否终止后续队列 Console.WriteLine($"工作流执行失败: {ex.Message}"); } finally { await ProcessQueueAsync(); // 递归处理下一个任务 } } } }
4. 调用示例
// 初始化依赖 var someService = new SomeService(); var requestManager = new WcfRequestManager(someService); var workflowQueue = new AsyncWorkflowQueue(); // 加入多个工作流 workflowQueue.EnqueueWorkflow(() => new ProcessWorkflow(requestManager).ExecuteAsync()); workflowQueue.EnqueueWorkflow(() => new ProcessWorkflow(requestManager).ExecuteAsync());
核心优化点
- 摆脱事件驱动的繁琐,用
TaskCompletionSource将WCF回调转换为异步Task,逻辑更线性。 - 业务流程通过
await串联多个请求,代码可读性和可维护性大幅提升。 - 异步队列利用
Task状态管理任务流转,避免手动维护当前任务和事件绑定的笨拙实现。
内容的提问来源于stack exchange,提问作者VaultBoy13
相关产品推荐
相关产品推荐

