async需要等待IObserver的任务

时间:2014-10-16 16:28:26

标签: 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))
    {


        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类,以便传播到任何希望收听的类。这样做的原因是,也可能在请求和响应之间接收广播消息,也可能等待响应的其他数据包(尽管技术上不应该发生这种情况)。

1 个答案:

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