我已阅读How to wait for a BackgroundWorker to cancel?的答案,但我无法找到解决我的具体问题的方法:
我的应用必须加载大量数据,但在大多数情况下,应用启动后不会立即需要这些数据。
为了最大限度地减少用户实际请求数据时的延迟,我使用BackgroundWorker加载它,后者在应用启动时启动。希望当用户请求数据时,BackgroundWorker已完成。
但在某些情况下,可能没有。在这些情况下,我想在向用户显示任何内容之前等待加载完成。
我能想到的所有技术都有竞争条件:例如,如果我设置AutoResetEvent
,当用户请求数据时我不能使用WaitOne()
,因为{{1可能已经发出信号;如果我在调用WaitOne之前添加一个布尔AutoResetEvent
标志并检查它,那么在ckecing之后可能会将loading_complete
设置为true,但在WaitOne调用之前,它将永远不会返回...
有什么想法吗?
编辑:感谢@ 500-InternalServerError的解决方案;使用loading_complete
效果很好。感谢其他人的建议。
答案 0 :(得分:0)
一旦在WorkCompleted事件处理程序
中完成BackgroundWorker,您就会发生任何事情答案 1 :(得分:0)
使用由BackgroundWorker
锁定的简单互斥锁,并让任何其他线程等待完成获取并释放它。完成BackgroundWorker
后,让它释放锁定,所有其他线程应该能够继续工作。
可能有一些特定的C#方式(我认为Monitor class可能很方便)。
更新:实际上,解决问题所需的对象是一种作为锁存器的条件变量形式,并且如OP所述,ManualResetEvent
涵盖了特定需求。
答案 2 :(得分:0)
后台工作程序支持RunWorkerCompleted事件。此事件可用于确定加载是否已完成。
有两个条件
为了减少事情的复杂性,可以添加一个布尔成员变量,当后台工作程序开始加载数据时,该变量将设置为false。加载数据后,将触发runworkercompleted事件,该事件将变量设置为true,这将帮助您确定数据是否已加载。
当用户请求数据时,您可以设置标志/另一个bool变量,例如
WaitingForData = true;
当触发RunWorkerCompleted事件时,它将检查WaitingForData的状态,如果为true,则显示数据。这样,您就不需要等待线程完成了。
使用此方法可以帮助您避免任何竞争条件或线程间通信。
答案 3 :(得分:-1)
使用布尔标志,在后台工作程序完成事件处理程序中将其设置为true。
当您需要检查数据是否已加载时,只需检查变量。
确保在尝试访问它之前锁定它以避免竞争条件。
如果数据在请求时没有准备就绪,那么您可以在此时向后台工作人员完成事件添加另一个事件处理程序,该事件执行需要对数据执行的操作。