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

Senerio

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

可能解决方案

我想使用线程来消除模拟的浏览器挂起。 我之前使用过Thread类并听说过ThreadPool 。 但是,我刚在这篇文章中找到了BackgroundWorker

MSDN声明 :

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

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

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

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

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

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

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

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

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

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

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

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

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

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