繁体   English   中英

具有异步/等待,RX和LINQ的异步消息处理

[英]Asynchronous message processing with async/await, RX and LINQ

我将Reactive Extensions与async / await结合使用以简化套接字协议的实现。 当特定消息到达时(例如,向每个“ ping”消息发送“ pong”),必须执行一些操作,还有一些方法,我们必须异步地等待某些特定的响应。 以下示例说明了这一点:

private Subject<string> MessageReceived = new Subject<string>();

//this method gets called every time a message is received from socket
internal void OnReceiveMessage(string message)
{
    MessageReceived.OnNext(message);
    ProcessMessage(message);
}

public async Task<string> TestMethod()
{
    var expectedMessage = MessageReceived.Where(x => x.EndsWith("D") && x.EndsWith("F")).FirstOrDefaultAsync();
    await SendMessage("ABC");

    //some code...

    //if response we are waiting for comes before next row, we miss it
    return await expectedMessage;
}

TestMethod()将“ ABC”发送到套接字,并在收到例如“ DEF”(在此之前可能还有其他消息)时继续执行。

这几乎可以用,但是有比赛条件。 似乎这段代码直到return await expectedMessage;才会侦听消息return await expectedMessage; 这是一个问题,因为有时消息会在此之前到达。

FirstOrDefaultAsync在这里不能很好地工作:在await行之前,它不会订阅,这使您处于竞争状态(如您所指出的)。 替换方法如下:

    var expectedMessage = MessageReceived
        .Where(x => x.EndsWith("D") && x.EndsWith("F"))
        .Take(1)
        .Replay(1)
        .RefCount();

    using (var dummySubscription = expectedMessage.Subscribe(i => {}))
    {
        await SendMessage("ABC");

        //Some code... goes here.

        return await expectedMessage;
    }

.Replay(1)确保新的订阅获得最新的条目(假定存在)。 它仅在有订户在侦听的情况下dummySubscription ,因此是dummySubscription

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM