我有一个IObserver类,它将数据包写入流并等待正确的响应,但是我对部分代码不满意:
bool ResponseReceived = false;
public async Task<IResponse> WriteAsync(Stream stream, bool returnResponse = false, bool flush = true, CancellationToken token = default(CancellationToken))
{
if (returnResponse)
{
//subscribe to IObserveable
PacketRouter router = new PacketRouter();
Subscribe(router);
//write the packet to the stream
await base.WriteAsync(stream, flush, token);
//I dont like the way this is done, is it possible to use task.WhenAny or WhenAll or even something I havent tried
if (!ResponseReceived)
{
var ts = TimeSpan.FromSeconds(Timeout);
DateTime maximumTime = DateTime.Now + ts;
while (!ResponseReceived && DateTime.Now < maximumTime)
{
await Task.Delay(10);
}
}
//Unsubscribe when the correct type of packet has been received or it has timed out
Unsubscribe();
}
else
{
//we dont need the return packet so we will just write to the stream and exit
await base.WriteAsync(stream, flush, token);
}
//return the response packet
return ResponseData;
}
public virtual void OnNext(Packet packet)
{
//when a packet is received, validate it
if (ValidResponse(packet))
{
//if valid set the response data
ResponseData.Payload = packet.Payload;
ResponseReceived = true; //The right to return the response is set here
}
}
我尝试过使用TaskCompletionResult和Task.WaitAny(responseReceived,TaskDelay(ts));但我也无法让它发挥作用。 有更好的方法吗?!?
更新了更多内容:
Write类不读取数据包。一个单独的类(PacketHandler)执行此操作,然后将其传递给IObservable类,以便传播到任何希望收听的类。这样做的原因是,也可能在请求和响应之间接收广播消息,也可能等待响应的其他数据包(尽管技术上不应该发生这种情况)。
答案 0 :(得分:2)
您可以直接等待观察,如下:
var router = new PacketRouter();
// write the packet to the stream
await base.WriteAsync(stream, flush, token);
try
{
// await the observable PacketRouter.
Packet p = await router
.FirstAsync()
.Timeout(DateTime.Now.AddSeconds(Timeout));
}
catch(TimeoutException)
{
// ...
}