.net 使用数据流和RX停止处理的连续数据流
我已经设置了一个系统,可以无限期地从队列中读取消息,然后使用Rx和.net 使用数据流和RX停止处理的连续数据流,.net,async-await,system.reactive,tpl-dataflow,.net,Async Await,System.reactive,Tpl Dataflow,我已经设置了一个系统,可以无限期地从队列中读取消息,然后使用Rx和TPL数据流将它们分发出去 出于某种原因,在几百条消息之后,ActionBlock停止运行挂起,我不知道为什么this.GetMessages()继续启动,但this.ProcessMessages不再启动 var source = Observable .Timer(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(1)) .SelectMany(x
TPL数据流将它们分发出去
出于某种原因,在几百条消息之后,ActionBlock停止运行挂起,我不知道为什么this.GetMessages()
继续启动,但this.ProcessMessages
不再启动
var source = Observable
.Timer(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(1))
.SelectMany(x => this.GetMessages());
var actionBlock = new ActionBlock<List<QueueStream>>(
this.ProcessMessages,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount * 2,
});
using (source.Subscribe(actionBlock.AsObserver()))
{
while (this.Run)
{
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
actionBlock.Complete();
await actionBlock.Completion;
var源=可观测
.Timer(TimeSpan.From毫秒(1),TimeSpan.From毫秒(1))
.SelectMany(x=>this.GetMessages());
var actionBlock=新actionBlock(
这个.ProcessMessages,
新的ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism=Environment.ProcessorCount*2,
});
使用(source.Subscribe(actionBlock.AsObserver()))
{
while(this.Run)
{
等待任务延迟(时间跨度从秒(1));
}
}
actionBlock.Complete();
等待动作块完成;
读者-请注意,这实际上会继续运行
private async Task<List<QueueStream>> GetMessages()
{
var messageList = new List<QueueStream>();
var taskList = new List<Task>();
// Add up to N items in our queue
for (var i = 0; i < 25; i++)
{
var task = this
.ReadAndParseQueue()
.ContinueWith(async queueStreamTask =>
{
var queueStream = await queueStreamTask;
if (queueStream != null)
{
messageList.Add(queueStream);
}
});
taskList.Add(task);
}
await Task.WhenAll(taskList);
return messageList;
}
专用异步任务GetMessages()
{
var messageList=新列表();
var taskList=新列表();
//在我们的队列中最多添加N个项目
对于(变量i=0;i<25;i++)
{
var task=this
.ReadAndParseQueue()的
.ContinueWith(异步队列流任务=>
{
var queueStream=等待queueStreamTask;
if(queueStream!=null)
{
messageList.Add(queueStream);
}
});
任务列表。添加(任务);
}
等待任务。WhenAll(任务列表);
返回消息列表;
}
作者-在几百条消息之后,这条消息不再受到攻击
private async Task ProcessMessages(List<QueueStream> streams)
{
var tasks = new List<Task>();
foreach (var queueStream in streams)
{
tasks.Add(this.ProcessMessage(queueStream));
}
await Task.WhenAll(tasks);
}
专用异步任务处理消息(列表流)
{
var tasks=新列表();
foreach(流中的var queueStream)
{
tasks.Add(this.ProcessMessage(queueStream));
}
等待任务。何时(任务);
}
您确定您的源代码在这种情况下保持运行吗?您的代码中有一个无限循环,但是,如果出现错误或此.Run
未设置,它将停止,然后您有以下行:
actionBlock.Complete();
await actionBlock.Completion;
这实际上阻止了actionBlock
接受新的mesasge,因此永远不会调用ProcessMessages
,因为消息会被忽略。您确实需要提供一个。我们可以复制粘贴并运行复制此问题的代码。@ChrisActionBlock
的状态是什么一旦挂起,很可能是出现故障。在等待
完成之前,不会观察到从ProcessMessages
中引发的任何异常。在您的情况下,如果始终设置了此选项,则不会发生此异常。运行
。