用 TaskCompletionSource 来做多线程间的数据同步

发布时间 2023-08-16 16:12:25作者: cchong005
 public abstract class HunClientBase
    {
        protected ComunicationConfig _ComunicationConfig;
        protected HubConnection _HubConnection;
        private TaskCompletionSource<string> requestCompletionSource;
        protected HunClientBase(string route) 
        {
            _ComunicationConfig = AppSettings.GetValue<ComunicationConfig>("ComunicationConfig");
            if (_ComunicationConfig is null || string.IsNullOrWhiteSpace(_ComunicationConfig.SignalRUrl)) 
                throw new ArgumentNullException("HunClientBase 未读取 SignalRUrl");

            _HubConnection = new HubConnectionBuilder()
                .WithUrl($"{_ComunicationConfig.SignalRUrl.TrimEnd('/')}/{route}")
                .WithAutomaticReconnect()
                .Build();

            _HubConnection.On<string>("ClientHubReceive", ClientHubReceive);
        }
        /// <summary>
        /// SignalR 请求,并等待回复
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="methodName"></param>
        /// <param name="paraments"></param>
        /// <returns>json</returns>
        public async Task<string> SignalRequestAsync(string methodName,params object[]? paraments)
        {
        if (_HubConnection.State == HubConnectionState.Disconnected)
        {
            await _HubConnection.StartAsync();
        }
            try
            {
                switch (paraments?.Length)
                {
                    case 1:
                        await _HubConnection.SendAsync(methodName,  paraments[0]);
                        break;
                    case 2:
                        await _HubConnection.SendAsync(methodName,  paraments[0], paraments[1]);
                        break;
                    case 3:
                        await _HubConnection.SendAsync(methodName,  paraments[0], paraments[1], paraments[2]);
                        break;
                    case 4:
                        await _HubConnection.SendAsync(methodName,  paraments[0], paraments[1], paraments[2], paraments[3]);
                        break;
                    case 5:
                        await _HubConnection.SendAsync(methodName,  paraments[0], paraments[1], paraments[2], paraments[3], paraments[4]);
                        break;
                    case 6:
                        await _HubConnection.SendAsync(methodName,  paraments[0], paraments[1], paraments[2], paraments[3], paraments[4], paraments[5]);
                        break;
                    default:
                        await _HubConnection.SendAsync(methodName);
                        break;
                }
                requestCompletionSource = new TaskCompletionSource<string>();
                return await requestCompletionSource.Task;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        protected void ClientHubReceive(string json)
        {
        requestCompletionSource.TrySetResult(json);
        }
    }

这是一个SignalR客户端,提交数据,和回调数据是异步的,你没法知道什么时候回调函数被执行;所以要在提交数据的函数 SignalRequestAsync 里返回服务端的回调数据就可以用到 TaskCompletionSource;