簡體   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