【问题标题】:TPL Dataflow Blocks Running On UI Thread在 UI 线程上运行的 TPL 数据流块
【发布时间】:2014-05-08 13:03:52
【问题描述】:

我正在构建一个数据流管道来执行自然流中的各种处理(主要是 I/O,但也有一些 CPU 处理)。流程目前处于这种基本模式:

  1. 从文件中加载数据
  2. 使用转换块解析记录
  3. 通过 REST 将对象序列化并上传到服务器

此处理管道可以自动启动,也可以通过 GUI 启动。因为当它从 GUI 启动时,我想向最终用户提供进度消息。如果我在第 1 步和第 2 步之间添加 BufferBlock 并在第 3 步之后添加 ActionBlock 并将它们设置为在与 UI 相同的线程上运行,其他块是否仍会使用自己的线程池在 UI 上运行?

我正在查看这篇 MSDN 文章:http://msdn.microsoft.com/en-us/library/hh228605(v=vs.110).aspx,但关于这种行为并不是很清楚。我可以从可以在 UI 线程上运行的管道中触发一个事件来完成此操作吗?

编辑:管道将从 UI 上的 BackgroundWorker 对象启动,而不是直接从 UI 线程启动。

【问题讨论】:

  • 您是否使用DataflowBlockOptions.TaskScheduler 使其运行UI 线程?一段代码会有所帮助。
  • @Noseratio 这更像是一个理论问题。我还在计划这个功能。截至目前,它还没有报告进度。使用DataflowBlockOptions.TaskScheduler 是我要告诉那些特定块在 UI 线程上运行的方式。
  • 我会使用Progress<T> 模式,而不是使用 UI 线程 TaskScheduler。
  • 我认为你在这里不需要BackgroundWorker。只需在 UI 线程上创建 Progress<T>(它确实捕获 s. 上下文并在内部使用 sc.Post)。然后在取得进展的任何地方从您的 Dataflow 管道中调用它。
  • @Noseratio 感谢您的建议。我会调查一下。

标签: c# multithreading user-interface dataflow tpl-dataflow


【解决方案1】:

多亏了 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&lt;int&gt; 对象并将它们传递给异步 ProcessData 方法。每当在异步处理方法中调用 Process&lt;T&gt;.Report() 方法时,UI 都会毫无问题地更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2013-12-18
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    相关资源
    最近更新 更多