用 TaskCompletionSource 来做多线程间的数据同步
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;