Asp.Net 中有没有办法与运行 Parallel.Foreach 的后台线程进行通信

Posted

技术标签:

【中文标题】Asp.Net 中有没有办法与运行 Parallel.Foreach 的后台线程进行通信【英文标题】:Is there a way in Asp.Net to communicate with a background thread running Parallel.Foreach 【发布时间】:2020-08-19 12:09:03 【问题描述】:

场景

    服务器必须处理一组报告,每个报告包含 n 个员工 UI 接受大量输入并触发处理报告的调用 服务器上的进程调用使用HostingEnvironment.QueueBackgroundWorkItem 排队到后台线程 在此后台线程中运行的函数使用Parallel.ForEach 并行化报表处理逻辑 UI 基本上显示了一个包含报告列表的简单网格,每个报告都有一个 status,它通过 SignalR 从服务器接收更新

这里的挑战是我们需要能够从 UI 中取消每个报告。但报告处理逻辑在Parallel.ForEach 内。我确实看到了有关CancellationToken 的文档,但这会破坏整个循环。我正在寻找一种与Parallel.ForEach 中运行的每个任务进行通信的方法,并指示当取消请求来自 UI 时是否必须取消它。

这可能吗?或者是否有其他方法?

【问题讨论】:

当然,如果您在字典等对象中注册报告,并且在处理过程中,您的处理器将在该字典中检查一个令牌以停止处理...然后,当您发送取消命令时,您会检查它某些作业,如果存在,每个报告的某些键,然后设置取消标志.....或者,您可以创建具有多个消费者的生产者-消费者设置,每个消费者都使用Task.Run 开始,然后单独使用令牌。 为什么你认为使用CancellationToken 会“打破整个循环”? @Enigmativity 我看到如果我们有一个 CancellationToken 被发送到这个循环中,并抛出一个异常,它将打破循环,不是吗? @user11944367 - CancellationToken 不必抛出。您只需检查.IsCancellationRequested 属性,看看是否需要取消操作。 【参考方案1】:

Take a look at the documentation here 关于在并行循环中处理异常。实际上,您可以构建它,以便可以在循环迭代中捕获抛出的异常,并且您可以控制何时捕获哪些异常。

然后,构建一个数据结构,其中包含一个任务、一个 CancellationTokenSource 以及一些识别它所绑定到的报表的方法。使用它自己的 CancellationTokenSource 设置该结构中的每个任务,基于该源为任务设置取消令牌,并设置您的后台工作人员以迭代该结构的集合并从那里启动任务。然后如果你需要取消,你可以通过ID访问集合中的包含结构,使用CancellationTokenSource.Cancel()方法将令牌源翻转为取消,任务将停止并抛出一个OperationCanceledException,你可以在循环迭代中捕获并忽略。

【讨论】:

我看到了这种方法的优点。会尝试

以上是关于Asp.Net 中有没有办法与运行 Parallel.Foreach 的后台线程进行通信的主要内容,如果未能解决你的问题,请参考以下文章

mac 系统如何运行 asp

在子文件夹中运行 ASP.NET 网站

在 asp.net 核心的构建后事件中运行 dotnet publish

有没有办法让 Asp.net 零公共站点(Asp.net MVC)中的实时登录用户?

ASP.NET Web API + 长时间运行的操作取消

在同一个端口上运行 Angular 和 ASP.NET Web API