感谢Noseratio的建议,我实际上重新设计了如何做到这一点,并能够没有问题地工作。我删除了BackgroundWorker
的对象,因为它不是真的有必要。相反,我将整个数据流封装在异步方法中,该方法将各种Progress<T>
参数用作进度更新的回调。由于Progress<T>
的Report()
方法在预先存在的块中调用,因此没有使用额外的TPL块来发布进度。此外,由于这是一个异步函数,表示数据流的任务不在UI线程上运行,而是在线程池线程上运行。由此可见,Progress<T>
对象的回调会在创建它们的线程上运行,因为在构建期间它们会捕获当前的同步上下文。以下是对解决我的问题的例子:
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
}
然后在UI中,我创建了Progress<int>
对象,并通过他们到异步ProcessData
方法。无论何时在异步处理方法中调用Process<T>.Report()
方法,UI均会更新而不会出现问题。
您是否在使用'DataflowBlockOptions.TaskScheduler'使其运行UI线程?一段代码会有帮助。 – Noseratio
@Noseratio这更多的是一个理论问题。我仍然计划这个功能。截至目前,它没有报告进展情况。使用'DataflowBlockOptions.TaskScheduler'是我如何告诉那些特定的块在UI线程上运行。 – JNYRanger
我会使用'Progress'模式,并没有诉诸UI线程TaskScheduler。 –
Noseratio