我有需要使用的第 3 方 WebSocket,请求以一种方法发送,响应以另一种方法给出。如何将这种类型的模式转换为更典型的异步/等待 TPL 任务,该任务将支持取消(通过令牌)、继续和所有其他好东西。
这是我到目前为止想出的,虽然我不确定它是否有效。我要到星期一才能测试它。
所以这是我的问题:
这行得通吗?
我一直在阅读关于
TaskCompletionSource
. 有没有更好的方法来做这一切TaskCompletionSource
?我真的不喜欢锁,因为我知道它有可能会阻塞很长时间,但我不确定如何做得更好,因为如果我不锁定第二个调用,
AsyncGetPositions
可能已经清除任何位置回来。即使
lock
我知道如果有超时或取消会产生问题,所以也许我只是删除取消令牌。我唯一能想到的另一件事是创建多个经过身份验证并准备好处理请求的客户端,然后像处理这些类型请求的线程池一样管理它们,但我不会很快这样做除此之外... idk。private object GetPositionsLock = new object(); private IEnumerable<Position> Positions { get; } = new List<Position>(); private Task PositionsReturned { get; set; } public async Task<List<Position>> AsyncGetPositions(CancellationToken token) { try { lock (GetPositionsLock) { Positions.Clear(); IbWebSocket.reqPositions(); PositionsReturned = new Task(null, token, TaskCreationOptions.None); PositionsReturned.GetAwaiter().GetResult(); return token.IsCancellationRequested ? null : Positions.ToList().Where(x => x.Shares != 0).ToList(); } } catch (TimeoutException ex) { //LogTimeout throw; } catch (Exception ex) { //LogError throw; } } /// <summary> /// Provides a position to the reqPositions() method. When the last position has been received positionEnd() is called. /// </summary> /// <param name="contract"></param> /// <param name="value"></param> /// <param name="account"></param> public void position(string account, Contract contract, double value) { try { Positions.Concat(new Position(account, contract, value)); } catch (Exception ex) { //LogError throw; } } /// <summary> /// Indicates all the positions have been transmitted. /// </summary> public void positionEnd() { PositionsReturned = Task.CompletedTask; }