.net 使用数据流和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

我已经设置了一个系统,可以无限期地从队列中读取消息,然后使用Rx和
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
,因为消息会被忽略。

您确实需要提供一个。我们可以复制粘贴并运行复制此问题的代码。@Chris
ActionBlock
的状态是什么一旦挂起,很可能是出现故障。在
等待
完成之前,不会观察到从
ProcessMessages
中引发的任何异常。在您的情况下,如果始终设置了
此选项,则不会发生此异常。运行