當我在 XREAD 程式中設定停止點時什么都不做。也許我需要配置這個 XREAD 命令?
public async void ListenTask()
{
var readTask = Task.Run(async () =>
{
while (!Token.IsCancellationRequested)
{
var result = db.StreamRead(streamName, "$", 1);
if (result.Any())
{
var dict = ParseResult(result.Last());
var sb = new StringBuilder();
foreach (var key in dict.Keys)
{
sb.Append(dict[key]);
}
Console.WriteLine(sb.ToString());
}
await Task.Delay(1000);
}
});
}
uj5u.com熱心網友回復:
這是對 StackExchange.Redis 的非法操作
由于其獨特的多路復用架構,StackExchange.Redis(您似乎正在使用的庫)不支持阻塞XREAD操作。這是因為通過互動式界面的所有命令(基本上所有非發布/訂閱的命令)都使用相同的連接。如果您阻止其中一個連接,則應用程式中依賴于多路復用器的所有其他內容都將被備份,等待阻止完成。StackExchange.Redis 庫實際上甚至將$id 視為非法 id,畢竟它的唯一目的是阻止。最有可能發生的事情(你看不到它發生,因為它被同步背景關系吞噬了)var result = db.StreamRead(streamName, "$", 1);是拋出一個 InvalidOperationException:System.InvalidOperationException: StreamPosition.NewMessages cannot be used with StreamRead.
解決方法
在這種情況下,有 2 個潛在的解決方法,首先,您可以將 poll 與XRANGE命令一起使用,而不是使用阻塞讀取。
var readTask = Task.Run(async () =>
{
var lastId = "-";
while (!token.IsCancellationRequested)
{
var result = await db.StreamRangeAsync("a-stream", lastId, " ");
if(result.Any()
{
lastId = result.Last().Id;
}
await Task.Delay(1000);
}
});
您已經有效地進行了執行緒睡眠,因此此輪詢操作可能足以滿足您的需求。
如果您確實需要執行阻塞操作,則必須使用不同的庫,如果您嘗試使用 StackExchange.Redis(您可能會使用Execute/ExecuteAsync命令強制解決問題),您可能會嚴重降低其性能。
使用ServiceStack.Redis和CsRedis的文章可在redis 開發者網站上找到(我是它們的作者)
最后一件事
可能希望確保在發出這些命令時盡可能異步,您在異步背景關系中使用同步 XREAD 命令(通常 StackExchange.Redis 中的每個命令都有一個可以使用的同步/異步版本- 盡可能使用異步)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/449539.html
