1

我已阅读如何等待 BackgroundWorker 取消的答案?,但我找不到解决我的具体问题的方法:

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

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

但是,在某些情况下,它可能没有。在这些情况下,我想等待加载完成,然后再向用户显示任何内容。

我能想到的所有技术都有竞争条件:例如,如果我设置了一个AutoResetEvent,当用户请求数据时我不能使用WaitOne(),因为AutoResetEvent可能已经发出信号;如果我添加一个布尔loading_complete标志并在调用 WaitOne 之前检查它,loading_complete可能会在 ckecing 之后设置为 true,但在 WaitOne 调用之前,它永远不会返回......

任何想法?

编辑:感谢@500-InternalServerError 的解决方案;使用ManualResetEvent效果很好。感谢其他所有人的建议。

4

4 回答 4

0

You put whatever should happen once the BackgroundWorker is done in the WorkCompleted event handler

于 2012-12-14T23:05:02.233 回答
0

使用由 锁定的简单互斥体BackgroundWorker,并让任何其他线程等待完成以获取和释放它。一旦BackgroundWorker完成,让它释放锁,所有其他线程应该能够继续他们的工作。

可能有一些特定的 C# 方法可以做到这一点(我认为Monitor 类可能很方便)。

更新:事实上,解决问题所需的对象是一种作为锁存器工作的条件变量,正如 OP 所提到的,ManualResetEvent它涵盖了该特定需求。

于 2012-12-14T23:24:47.023 回答
0

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

有两个条件

  • 工作人员完成后,用户已请求数据。

为了让事情变得不那么复杂,您可以添加一个布尔成员变量,当后台工作人员开始加载数据时,该变量将设置为 false。加载数据后,将触发 runworkercompleted 事件,该事件会将变量设置为 true,这将帮助您确定数据是否已加载。

  • 用户在工作完成之前请求数据(可以从上述布尔变量确定)并等待数据加载。

当用户请求数据时,您可以设置一个标志/另一个布尔变量,例如

等待数据 = 真;

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

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

于 2012-12-15T03:56:52.073 回答
-1

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

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

确保在尝试访问它之前将其锁定以避免竞争条件。

如果数据在被请求时尚未准备好,您可以在此时将另一个事件处理程序添加到后台工作人员完成事件,该事件执行需要对数据执行的操作。

于 2012-12-14T23:34:51.750 回答