【问题标题】:.NET threading solution for long queries用于长查询的 .NET 线程解决方案
【发布时间】:2010-06-10 21:16:53
【问题描述】:

Senerio

我们有一个记录事件的 C# .Net Web 应用程序。当事件被主管批准时,需要查询外部数据库。对该外部数据库的查询有时需要一段时间才能运行。这种延迟是通过浏览器体验到的。

可能的解决方案

我想使用线程来消除浏览器的模拟挂起。我以前用过Thread 类,听说过ThreadPool。但是,我刚刚在this post 中找到了BackgroundWorker

MSDN states:

BackgroundWorker 类允许您在单独的专用线程上运行操作。下载和数据库事务等耗时的操作可能会导致您的用户界面 (UI) 在运行时似乎停止响应。当您需要响应式 UI 并且面临与此类操作相关的长时间延迟时,BackgroundWorker 类提供了一种方便的解决方案。

BackgroundWorker 是处理长时间运行的查询时要走的路吗?

同时运行 2 个或更多 BackgroundWorker 进程会发生什么?它像游泳池一样处理吗?

【问题讨论】:

  • 抱歉,这是桌面应用程序还是网络应用程序?
  • @Eddie:C# 不支持线程。您问的是 .NET Framework,对吗?
  • @John C# 支持线程!
  • BackgroundWoker 在后台使用了.Net ThreadPool,所以如果你使用两个后台worker,就像调用了两次threadpool.queueuserworkitem。
  • @Eddie 小心。约翰是这种区别的坚持者。 C# 本身没有线程。 .net 框架(即Thread 类)提供线程支持。

标签: c# .net multithreading


【解决方案1】:

是的,BackgroundWorker 可以显着简化长时间运行操作的线程代码。关键是注册 DoWorkProgressChangedRunWorkerCompleted 事件。这些可以帮助您避免必须通过线程来回传递一堆同步对象来尝试确定操作的进度。

另外,我相信在 UI 线程上调用进度事件,避免调用 Control.Invoke 来更新您的 UI。

要回答您的最后一个问题,是的,线程是从 .NET 线程池中分配的,因此您虽然可以实例化任意数量的 BackgroundWorker 对象,但您只能运行线程池的并发操作数允许。

【讨论】:

  • 没错 - 进度和完成的事件被编组到 UI 线程(好吧,不管当前线程同步上下文说做什么,但对于 winforms/wpf 来说,那是 UI 线程)所以你不要必须自己做。
【解决方案2】:

如果您使用的是 .NET 4(或者可以使用 Rx 框架中的 TPL 反向端口),那么一个不错的选择是使用使用 LongRunning 提示创建的 Task

这提供了许多难以通过 ThreadPool 或 BackgroundWorker 完成的选项,包括允许在创建时指定延续,以及允许彻底取消和异常/错误处理。

【讨论】:

  • 目前,为 .Net 3.5 构建。
  • 我确实喜欢 Task 的类型化返回值。在 BackgroundWorker 中击败(对象)DoWorkEventArgs.Result。
  • @Eddie:您可以使用 Rx 框架获取 .NET 3.5sp1 的 TPL。这是一个比以前的线程模型 IMO 更干净的 API。
【解决方案3】:

我曾在类似的情况下运行过长时间的查询。我使用了委托提供的异步调用。您可以使用委托的 BeginInvoke 方法。

【讨论】:

  • 异步委托调用和后台工作人员都在后台使用线程池。如果它是一个需要运行的简单后台进程,并且不需要增加 IAsyncResult 的复杂性,那么 BackgroundWorker 是 IMO 更好的选择。
【解决方案4】:

BackgroundWrokerks 就像任何其他线程一样,接受它们可以被杀死或退出,而无需退出主线程和您的应用程序。

ThreadPool 使用 BackgroundWorkers 池。这是大多数多线程场景的首选方式,因为 .net 为您管理线程,并且它会重复使用它们而不是根据需要创建新线程,这是一个昂贵的过程。

此类线程场景非常适合处理器密集型代码。

对于发生在外部的查询,您还可以选择异步数据访问。您可以传递查询请求,并为其提供回调方法的名称,该方法将在查询完成时调用,而不是对结果执行某些操作(即更新 UI 状态或显示返回的数据)..

.Net 内置了对异步数据查询的支持 http://www.devx.com/dotnet/Article/26747

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2015-11-22
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多