You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 01:45:33