C# 在UI线程上运行的TPL数据流块
我正在构建一个数据流管道来执行自然发生流中的各种处理(主要是I/O,但有些是CPU处理)。该流程目前处于以下基本模式:C# 在UI线程上运行的TPL数据流块,c#,multithreading,user-interface,dataflow,tpl-dataflow,C#,Multithreading,User Interface,Dataflow,Tpl Dataflow,我正在构建一个数据流管道来执行自然发生流中的各种处理(主要是I/O,但有些是CPU处理)。该流程目前处于以下基本模式: 从文件加载数据 使用转换块解析记录 通过REST将对象序列化并上载到服务器 此处理管道可以自动启动,也可以通过GUI启动。因为当它从GUI启动时,我希望向最终用户提供进度消息。如果我在第1步和第2步之间添加一个BufferBlock,在第3步之后添加一个ActionBlock,并将选项设置为在与UI相同的线程上运行,那么其他块是否仍会使用自己的线程池从UI上运行 我正在看这篇M
BufferBlock
,在第3步之后添加一个ActionBlock
,并将选项设置为在与UI相同的线程上运行,那么其他块是否仍会使用自己的线程池从UI上运行
我正在看这篇MSDN文章:但关于这种行为,我不是很清楚。我可以从管道中触发一个可以在UI线程上运行的事件来完成这个任务吗
编辑:管道将从UI上的
BackgroundWorker
对象启动,而不是直接从UI线程启动。多亏了Noseratio的建议,我实际上重新设计了如何完成这项工作,并且能够让它毫无问题地工作。我删除了BackgroundWorker
对象,因为它不是必需的。相反,我将整个数据流包装在一个异步方法中,该方法将各种Progress
参数作为进度更新的回调。由于在先前存在的块中调用了progress
的Report()
方法,因此没有使用额外的TPL块来发布进度。此外,由于这是一个异步函数,因此表示数据流的任务不是在UI线程上运行,而是在线程池线程上运行。主要的一点是,Progress
对象的回调在创建它们的线程上运行,因为在构建过程中它们捕获了当前的同步上下文。以下是解决我的问题的示例:
public static async Task ProcessData(IProgress<int> ReadProg, IProgress<int> UploadProg)
{
var loadBuffer = new BufferBlock<string>();
var parseBlock = new TransformBlock<string, MyObject>(async s =>
{
if(await DoSomething(s))
ReadProg.Report(1);
else
ReadProg.Report(-1);
});
...
//setup of other blocks
//link blocks
//feed data into pipeline by adding data into the head block: loadBuffer
//await ALL continuation tasks of the blocks
}
public静态异步任务ProcessData(IProgress ReadProg、IProgress UploadProg)
{
var loadBuffer=new BufferBlock();
var parseBlock=newtransformblock(异步s=>
{
如果(等待剂量测定)
ReadProg.报告(1);
其他的
ReadProg.报告(-1);
});
...
//其他区块的设置
//连接块
//通过将数据添加到头块loadBuffer,将数据馈送到管道中
//等待模块的所有继续任务
}
然后在UI中,我创建了
Progress
对象,并将它们传递到异步ProcessData
方法中。无论何时在异步处理方法中调用Process.Report()
方法,UI都会毫无问题地更新。是否使用DataflowBlockOptions.TaskScheduler
使其在UI线程中运行?一段代码将有助于理解这更多的是一个理论问题。我还在计划这个功能。到目前为止,它还没有报告进展情况。使用DataflowBlockOptions.TaskScheduler
是我告诉那些特定块在UI线程上运行的方式。我会使用Progress
模式,而不是求助于UI线程TaskScheduler。我想这里不需要BackgroundWorker
。只需在UI线程上创建Progress
(它会捕获s.context并在内部使用sc.Post
)。然后从您的数据流管道调用它,无论进展如何。谢谢您的建议。我会调查的。