需要等待IObserver的异步任务

本文关键字:异步 任务 IObserver 等待 | 更新日期: 2023-09-27 18:26:50

我有一个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.WetAny(responseSReceived,TaskDelay(ts));但我也无法让它发挥作用。有更好的方法吗?!?

更新了更多上下文:

Write类不读取数据包。一个单独的类(PacketHandler)执行此操作,然后将其传递给IObservable类,以便分发给任何希望侦听的类。原因是还接收到可能在请求和响应之间的广播消息,以及可能等待响应的其他数据包(尽管从技术上讲,这不应该发生)。

需要等待IObserver的异步任务

您可以直接等待可观察到的,如下所示:

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)
{
    // ...
}