2012-12-14 44 views
1

我从How to wait for a BackgroundWorker to cancel?阅读的答案,但我无法找到一个解决我的具体的问题:如何等待BackgroundWorker完成?

我的应用程序加载大量的数据,但在大多数情况下,这些数据不会被立即要求应用程序启动后。

为了最大限度地减少用户实际请求数据时的延迟,我使用BackgroundWorker加载它,该应用程序在应用程序启动时启动。希望当用户请求数据时,BackgroundWorker已经完成。

然而,在某些情况下,它可能没有。在这些情况下,我想在向用户显示任何内容之前等待加载完成。我可以想到的所有技术都有竞争条件:例如,如果我设置了AutoResetEvent,当用户请求数据时,我不能使用WaitOne(),因为AutoResetEvent可能已经发出信号;如果我添加一个布尔值loading_complete标志并在调用WaitOne之前检查它,loading_complete可能会在ckecing之后设置为true,但在WaitOne调用之前将永远不会返回...

任何想法?

编辑:感谢解决方案的@ 500-InternalServerError;使用ManualResetEvent的作品很棒。感谢其他人的建议。

+0

如果使用.net 4.0或更高版本,可以使用'Task'。 –

+0

@HamletHakobyan不幸的是,我在Windows Phone上SilverLight,它没有'Task' ... –

+1

好吧,只需在RunWorkerCompleted事件中启用一个按钮即可。 –

回答

0

你把一次的BackgroundWorker在WorkCompleted事件处理

+0

当BackgroundWorker完成时,至少没有发生任何事情,我知道当我启动BackgroundWorker时:我只使用它在 –

+0

之后加载的数据我认为Baboon意味着BackgroundWorker应该触发该事件,并且所有其他线程都应该等待在这个事件之前恢复他们的工作。 – didierc

+0

@didierc:据我所知,但当我输入需要数据完全加载的应用程序部分时,我无法知道事件是否已经触发。换句话说,当我到了需要等待数据的地步时,WorkCompleted事件可能会或可能没有开始,如果我使用布尔标志来检查我会遇到竞争条件。 –

0

用一个简单的互斥锁BackgroundWorker锁定做什么应该发生,并有其他线程等待完成获取和释放它。一旦完成BackgroundWorker,让它释放该锁,并且所有其他线程应该能够继续其工作。

可能有一些特定的C#方式做到这一点(我认为Monitor class可能会得心应手)。

更新:实际上,解决问题所需的对象是一种形式的条件变量,作为锁存器工作,并且,如OP所述,ManualResetEvent涵盖了该特定需求。

-1

使用布尔标志,在后台worker完成的事件处理程序中将其设置为true。

当您需要检查数据是否加载时,只需检查变量。

确保在尝试访问它之前先将其锁定,以避免竞争状况。

如果数据在请求时没有准备好,那么可以在该点添加另一个事件处理程序给后台工作人员已完成的事件,该事件需要完成数据处理。

0

后台工作者支持RunWorkerCompleted事件。该事件可用于确定加载是否已完成。

有两个条件

  • 用户请求数据工人完成后。

为了减少事情的复杂性,您可以添加一个布尔成员变量,当后台工作人员开始加载数据时,该变量将被设置为false。一旦数据加载完成,runworkercompleted事件将触发它将变量设置为true,这将帮助您确定数据是否加载。

  • 用户在worker完成之前(可以根据上述bool变量确定)请求数据并等待数据加载。

当用户请求的数据,则可以设置一个标志/另一个bool变量如

WaitingForData = TRUE;

当RunWorkerCompleted事件被触发时,它将检查WaitingForData的状态,如果它为true,它将显示数据。这样,你不需要等待线程完成。

使用此方法将帮助您避免任何竞态条件或线程间通信。

+0

这听起来像个好主意,但它并没有说明我的应用程序中有多个数据可视化页面,并且BackgroundWorker不知道将数据发送到哪个数据... @ 500-InternalServerError的解决方案工作正常好,但是。 –

+0

如果您有多个组件显示数据,则可以在多个位置使用该事件。 –

+0

考虑到UI布局的成本,使用数据呈现所有UI元素是不可行的,因为最后只会显示一个。 –