Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何等待后台工作人员完成?_C#_Multithreading - Fatal编程技术网

C# 如何等待后台工作人员完成?

C# 如何等待后台工作人员完成?,c#,multithreading,C#,Multithreading,我已经从中阅读了答案,但我找不到解决我具体问题的方法: 我的应用程序必须加载大量数据,但在大多数情况下,应用程序启动后不会立即需要这些数据 为了最大限度地减少用户实际请求数据时的延迟,我使用BackgroundWorker加载数据,该程序在应用程序启动时启动。希望当用户请求数据时,BackgroundWorker已经完成 然而,在某些情况下,它可能没有。在这些情况下,我希望在向用户显示任何内容之前等待加载完成 我能想到的所有技术都有竞争条件:例如,如果我设置了一个AutoResetEvent,当

我已经从中阅读了答案,但我找不到解决我具体问题的方法:

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

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

然而,在某些情况下,它可能没有。在这些情况下,我希望在向用户显示任何内容之前等待加载完成

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

有什么想法吗


编辑:感谢@500 InternalServerError提供的解决方案;使用
ManualResetEvent
非常有效。感谢大家的建议。

您将BackgroundWorker完成后应该发生的事情放到WorkCompleted事件处理程序中

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

可能有一些具体的C#方法可以做到这一点(我认为这可能很方便)


更新:事实上,解决问题所需的对象是一种用作闩锁的条件变量,并且,如OP所述,
ManualResetEvent
涵盖了该特定需要。

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

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

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


如果请求数据时数据未准备就绪,则可以在该点向后台工作程序完成事件添加另一个事件处理程序,该事件执行需要对数据执行的操作。

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

有两个条件

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

  • 用户已在worker完成(可通过上述bool变量确定)并等待加载数据之前请求数据
当用户请求数据时,您可以设置一个标志/另一个bool变量,例如

WaitingForData=true

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


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

如果您使用.net 4.0或更高版本,您可以使用
任务
@HamletHakobyan不幸的是,我使用的是SilverLight for Windows Phone,它没有
任务
…嗯,只需在RunWorkerCompleted事件中启用一个按钮。只需使用手动重置事件,在启动后台工作程序之前重置该事件,然后在主线程中等待。后台工作人员在唤醒主线程时设置此选项。在这种情况下,Wait将立即返回,这应该是您想要的。后台工作人员完成后不应发生任何事情,启动BackgroundWorker时,至少我什么都不知道。BackgroundWorker:我只使用它加载的数据,因为我认为Baboon可能意味着BackgroundWorker应该触发该事件,而所有其他线程都应该等待该事件,然后再继续工作。@didierc:我明白,但当我进入需要完全加载数据的应用程序部分时,我无法知道事件是否已经触发。换句话说,当我到达需要等待数据的点时,WorkCompleted事件可能已经触发,也可能尚未触发,如果我使用布尔标志进行检查,我将遇到竞争条件。@didierc然后,如果你需要完成bgw,但不能等他说“我完成了”,你需要重新思考如何完成它那么你就有了架构问题。@Clément我是说给你的,不是didierc;)这听起来是个好主意,但它不能解释我的应用程序中有多个数据可视化页面,而且后台工作人员不知道将数据发送到哪个页面@不过,500 InternalServerError的解决方案运行良好。如果有多个组件显示数据,则可以在多个位置使用事件。考虑到UI布局的成本,使用数据呈现所有UI元素是不可行的,考虑到最后只会显示一个。可能我无法理解您到底想要实现什么,但我察觉到您的应用程序存在架构问题。这种情况本来就不应该发生。如果你再多解释一点,我可以为你的问题提供高效的解决方案。谢谢,但我这边的问题已经基本解决了@这是一个很好的方法。