gpt4 book ai didi

c# - 如何将信息从 ThreadPool.QueueUserWorkItem 传递回 UI 线程?

转载 作者:太空狗 更新时间:2023-10-30 00:46:21 26 4
gpt4 key购买 nike

我有一个相当简单的线程问题。

我正在编写一个简单的实用程序,它将根据用户定义的参数运行各种 SQL 脚本。

为了保持 UI 响应并提供有关正在执行的脚本状态的反馈,我决定使用 ThreadPool.QueueUserWorkItem 来处理各种脚本(通过 SMO。)

但是,我对如何中继 SMO 将返回到 UI 线程的输出信息感到有点困惑。

对于此实用程序,我使用 WPF 和 MVVM 进行演示。我想我会有一个 ScriptWorker 类,我可以将参数和位置以及运行脚本的顺序传递给它。

在我运行每个脚本后,我想以某种方式将结果返回到 UI 线程,以便它更新输出窗口,然后我希望工作人员转到下一个任务。

我确定这是一个基本问题,但在查看 QueueUserWorkItem 并看到我实际上是通过回调开始工作后,我不确定我将如何完成我想要的喜欢完成。

我的假设基于这篇 Microsoft 文章:

http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx

感谢您提供信息!

最佳答案

QueueUserWorkItem 在技术上可以工作,但级别非常低。有更简单的方法。

我建议使用 .NET 4.0 的新 Task 功能。它完全按照您的意愿行事,包括将结果或错误条件同步到另一个线程(在本例中为 UI 线程)。

如果 .NET 4.0 不是一个选项,那么我会推荐 BackgroundWorker(如果您的后台处理不是太复杂),或者 Hans 提到的异步委托(delegate)。如果您使用异步委托(delegate),则使用 AsyncOperation 类将结果编码回 UI 线程。

Task 选项非常好,因为它可以非常自然地处理父/子任务。 BackgroundWorker 不能嵌套。另一个考虑因素是取消; TaskBackgroundWorker 内置了对取消的支持,但对于异步委托(delegate),您必须自己做。

Task 唯一比 BackgroundWorker 复杂一点的地方是进度报告。它不像 BackgroundWorker 那么简单,但我有一个包装器 on my blog以尽量减少这种情况。

总结一下,按优先顺序:

  1. Task - 支持正确的错误编码、结果概念、取消和父/子嵌套。它的一个弱点是进度报告并不简单(您必须创建另一个任务并将其安排到 UI 线程)。
  2. BackgroundWorker - 支持正确的错误编码、结果概念、取消和进度报告。它的一个弱点是它不支持父/子嵌套,这限制了它在 API 中的使用,例如,用于业务层。
  3. Delegate.BeginInvoke with AsyncOperation - 支持错误的正确编码、结果的概念和进度报告。但是,没有内置的取消概念(尽管可以使用 volatile bool 手动完成)。它也不支持父/子嵌套。
  4. Delegate.BeginInvoke with SynchronizationContext - 这与选项 (3) 相同,只是它直接使用 SynchronizationContext。代码稍微复杂一些,但权衡是支持父/子嵌套。所有其他限制与选项 (3) 相同。
  5. ThreadPool.QueueUserWorkItem with AsyncOperationSynchronizationContext - 支持进度报告的概念。取消遇到与选项 (3) 相同的问题。错误的编码并不容易(特别是保存堆栈跟踪)。此外,父/子嵌套只有在使用 SynchronizationContext 而不是 AsyncOperation 时才有可能。此外,此选项不支持结果的概念,因此任何返回值都需要作为参数传递。

如您所见,Task 是明显的赢家。除非 .NET 4.0 不是一个选项,否则应该使用它。

关于c# - 如何将信息从 ThreadPool.QueueUserWorkItem 传递回 UI 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3484135/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com