用于长查询的.NET线程解决方案

时间:2010-06-10 21:16:54

标签: c# .net multithreading

Senerio

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

可能的解决方案

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

MSDN states

  

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

在处理长时间运行的查询时,BackgroundWorker是可行的吗?

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

4 个答案:

答案 0 :(得分:2)

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

此外,我相信在UI线程上调用了进度事件,因此无需调用 Control.Invoke 来更新UI。

要回答您的上一个问题,是的,线程是从.NET线程池分配的,因此您可以根据需要实例化尽可能多的BackgroundWorker对象,但只能运行与线程池一样多的并发操作。允许。

答案 1 :(得分:1)

如果您正在使用.NET 4(或者可以使用Rx Framework中的TPL backport),那么一个不错的选择是使用Task提示创建的LongRunning

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

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

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

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