C# 需要等待IObserver的异步任务
我有一个IObserver类,它将数据包写入流并等待正确的响应,但是我对部分代码不满意:C# 需要等待IObserver的异步任务,c#,async-await,system.reactive,C#,Async Await,System.reactive,我有一个IObserver类,它将数据包写入流并等待正确的响应,但是我对部分代码不满意: bool ResponseReceived = false; public async Task<IResponse> WriteAsync(Stream stream, bool returnResponse = false, bool flush = true, CancellationToken token = default(CancellationToken))
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
}
}
bool ResponseReceived=false;
公共异步任务WriteAsync(Stream-Stream,bool-returnResponse=false,bool-flush=true,CancellationToken=default(CancellationToken))
{
如果(返回响应)
{
//订阅iObservable
PacketRouter路由器=新的PacketRouter();
订阅(路由器);
//将数据包写入流
wait base.WriteAsync(流、刷新、令牌);
//我不喜欢这样做,是否可以使用task.whany或whalll,甚至是我没有尝试过的东西
如果(!ResponseReceived)
{
var ts=TimeSpan.FromSeconds(超时);
DateTime maximumTime=DateTime.Now+ts;
而(!ResponseReceived&&DateTime.Now
我尝试过使用TaskCompletionResult和Task.WaitAny(responseReceived,TaskDelay(ts));但我也不能让它工作。
有更好的方法吗
更新了更多的上下文:
Write类不读取数据包。一个单独的类(PacketHandler)执行此操作,然后将其传递给一个IObservable类,以便分发给希望侦听的任何类。原因是也会收到广播消息,这些消息可能在请求和响应之间,其他数据包也可能在等待响应(虽然从技术上讲,这永远不会发生)。您可以直接等待可观察到的消息,如:
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)
{
// ...
}
您需要使用反应式扩展库来使用它吗?它是Microsoft Rx Linq包的一部分,即
Observable.GetAwaiter
扩展方法。