问题标签 [waithandle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1076 浏览

c# - 结合等待句柄?

我认为这里有点有趣。我有一个类负责将多个处理操作“多路复用”到固定数量的线程上。典型的情况是一种生产者/消费者问题,其中每个操作都包含一个 WaitHandle(在这种情况下,是跟踪队列中有多少项目的信号量)和一个要调用的委托。

例如,如果我有两个生产者(A 和 B),将项目生产到两个单独的队列中。我不是为每个生产者(A1、A2、B1、B2)创建两个消费者线程,而是将四个消费者“线程”多路复用到两个线程上。这个“多路复用器”的代码运行如下(稍微简化了一点):

我试图将此概念扩展到一个稍微复杂的示例,其中一个操作可能需要多个等待句柄才能在执行之前得到满足。我想知道是否有某种 WaitHandle.Combine(waitHandle1, waitHandle2) 调用可以将两个等待句柄组合成一个等待句柄。最终结果将是这样的:

加分?

虽然不是必需的,但如果等待句柄的组合可以相交,它也可能非常好。例如,像这样:

谢谢你的帮助

0 投票
1 回答
1443 浏览

vb.net - WaitHandle.WaitAll Runs before all Threads completed - VB.Net 4.0

I'm working on a program that scans a list of servers for different information.

Everything is working fine except sometimes I get errors when the threads are done. Either by the scan completing or the cancel button stopping the loop but letting the current threads continue.

I see the UI say the scan is complete but the progressUpdate tries to run again. I can solve the problem by making a longer thread.sleep after the waitall.

For the most part it waits to the last thread but I get an error sometimes saying it can't access the progressUpdate function because OperationsComplete has already been run.

I get the error at BackgroundWorker1.ReportProgress(_completedCount, ScanResult) below but it shouldn't be calling that because WaitAll should wait until the threads are complete.

Edit The array is empty when i break it. But somehow something runs still. Maybe I am missing catching one.

0 投票
2 回答
160 浏览

c# - 如何在运行时替换线程应该等待的 WaitHandle

我想知道如何在运行时安全地更改线程应该等待的 EventWaitHandle。

例如,假设有两个线程(A 和 C)通过 EventWaitHandles 同步。A 循环地完成它的工作,C 等待直到它收到来自 A 的通知,它可以开始做它的工作(例如,通过 AutoResetEvent)。图案是ACAC...

稍后启动一个新线程(B)(例如通过用户操作),它的工作应该在两个预先存在的线程之间以这种方式执行:A 完成它的工作,然后向 B 发出信号,一旦 B 完成它就向 C 发出信号。现在模式是ABCABC...

因此,在线程 C 等待与 A 共享的 EventWaitHandle 之前,应该有一个安全机制使 C 等待与 B 共享的另一个 EventWaitHandle。在我看来,棘手的部分是替换 C 使用的 EventWaitHandle,因为一旦这个完成后,我应该能够轻松启动 B,它将使用 EventWaitHandle 等待 A 作业,并使用 EventWaitHandle 发出 C 作业信号。该机制还应该提供一种安全卸载线程 B 并返回到只有线程 A 和 C 正在工作的初始情况的方法。

使用 EventWaitHandle 是否有安全的方法来完成此任务?如果没有,任何其他建议将不胜感激。

0 投票
3 回答
581 浏览

c# - 多线程:WaitAll 没有按预期等待

我有一个线程正在调用两个单独的线程来做一些工作。每当任何工作完成时,都会调用 Waithandle.Set(0 并且在父工作线程结束时,我想 WaitAll 让两者都完成,然后再继续。但是 priceA() 仍然首先出现,然后是 PriceB ()。

我错过了什么?

更新:

托儿:

0 投票
1 回答
231 浏览

c# - 哪种 Code Pattern 最适合处理循环和可变的动作流

我的场景是一个应用程序在实时数据上循环工作并且截止日期很紧。

我在每个周期对数据采取一系列行动。我有在每个周期发生的动作(让我们用大写字母来称呼它们,比如ABC ..)和其他只在每 x 个周期发生的动作(让我们用小写字母来称呼它们,比如def, ...)。一个流模式示例,有两个持续的动作,一个发生在 3 个周期的周期可能是(周期结束标记为“|”):

A - B - d | A - B | A - B | A - B - d |...

此外,该模式可以在运行时根据用户的输入而改变。因此可以从列表中添加或删除一些操作。例如,先前的模式通过删除B ,在A之后添加C ,在C之后添加e,周期为 2 个周期,会突然变成(以 '->' 标记的更改周期):

...| A - B - d | -> A - d - C - e | A - C | A - C - e | A - d - C | A - C - e | A - C | A - d - C - e |...

现在我手动启动线程,这些线程通过 WaitHandles 相互通信,如果操作很繁重,请使用 Parallel.For。然后,当模式发生变化时,我可能不得不终止某个线程,启动另一个线程,替换等待的 WaitHandle ......当模式发生变化时,我会出现死锁问题。我可以修复它们,但我想到有一个更灵活的解决方案会更好,这样如果我以后需要更改模式,我已经拥有所有工具来有效地完成它。

我对这个话题很陌生,但我认为(按照之前向我提出的建议我需要一种调度程序。

我已经阅读了有关 Windows Workflow Foundation 的一些内容(我目前不知道它是否适合我的情况)和其他解决方案,但我需要知道在花时间理解它之前采取的最佳方向。例如任务更适合这个?或者我应该坚持使用线程并创建一个调度程序类来管理所有可能的情况(在这种情况下,我已经看到关于模式更改的不同问题,如果你能更深入地研究这个问题,我会很高兴)?还是有更好的选择?

[编辑]当循环中的前一个主要动作( AB,...)终止
时,可以执行动作。次要动作(de,...)可以同时执行。例如,在A - B - d - e类型的循环中,动作B只能在A之后执行,动作d只能在B之后执行,动作e只能在B之后执行,也可能与d同时执行。此外,如果我不将两个连续的主要动作分组(在示例中,人们可能会认为AB由于它们的相互依赖性,可以组合成一个动作)这意味着在两个不同的线程中执行。这样做的原因是我使用循环缓冲区来存储中间结果(在示例中,结果来自A,稍后将由B使用)。缓冲区帮助我在实时过程中不丢失数据,以防由于某种原因在过程中出现延迟(事实上,无论循环中的最后一个动作已经完成不是)。

0 投票
1 回答
151 浏览

.net - .net - IPC - “排队”最古老的进程的工作首先触发

我有一个 .Net 2.0 应用程序,它处理数据、生成 Crystal Reports,然后将呈现的输出发送到打印机。大多数情况下,此应用程序是从 Win32 应用程序多次触发的。实际将呈现的报表发送到打印机所需的时间取决于数据的大小和/或 Crystal Report 的复杂性。
我的困惑是,无论报告是否准备好打印,我都需要让打印作业以与流程相同的顺序排队。因此,例如:

在上面的例子中,我需要进程 1 来打印第 1 个,然后是进程 2,然后是进程 3。但是,只需要按顺序打印报告——所有的“咀嚼”可以同时完成......

我一直在玩 Mutex 和 Semaphore,我已经在一个测试应用程序中达到了一个点,第一个进程将首先“打印”,但第二个和第三个(第四个、第五个等)将“打印”取决于在他们的“WaitOne”发行时。

我在这里走错路了吗?
我认为我需要的是某种机制,例如用于 IPC 的“Queued WaitHandle”...

0 投票
3 回答
276 浏览

.net - 是否有任何理由在 bool 上使用 WaitHandle 来标记取消?

我继承了一些线程代码,在查看它时,我发现了这样的结构(在后台线程方法中):

通常有一个公共或私有Stop()方法,如下所示:

我的问题是:在这里使用等待句柄可以提供什么?似乎这样做是为了确保停止发出信号是原子操作,但我认为写入布尔值无论如何都是原子的。如果是这种情况,是否有任何理由不只使用以下内容:

0 投票
6 回答
2063 浏览

c# - 我什么时候应该使用 WaitHandle 而不是锁

C#,什么时候我们应该使用WaitHandle而不是lock

0 投票
3 回答
17858 浏览

c# - 如何解除对 AutoResetEvent 对象调用 WaitOne 方法的线程的阻塞?

下面是一个具有“SomeMethod”方法的类,它说明了我的问题。

该方法被设计为线程安全的,将在不同的线程中调用。现在我的问题是,如何在任何时候解除对“theEvent”对象调用“WaitOne”方法的所有线程的阻塞?这个要求经常出现在我的设计中,因为我需要能够优雅地停止和启动我的多线程程序。在我看来,启动一个多线程程序相当简单,但要停止一个程序却很棘手。

这是我迄今为止尝试过的显然有效的方法。但这是标准方法吗?

“UnblockAll”方法是“SomeClass”类的成员。此处使用的技术基于WaitOne 方法的 MSDN 文档。我引用了以下文档的相关部分:

如果毫秒超时为零,则该方法不会阻塞。它测试等待句柄的状态并立即返回。

在 do..while 循环中,我调用Set 方法。这会释放一个可能由于调用 WaitOne 方法而阻塞的线程(编码在“SomeMethod”方法中)。接下来我测试“theEvent”对象的状态,以了解它是否已发出信号。该测试是通过调用带有超时参数的 WaitOne 方法的重载版本来完成的。我在调用 WaitOne 方法时使用的参数为零,根据文档,这会导致调用立即返回一个布尔值。如果返回值为真,则“theEvent”对象处于信号状态。如果在“SomeMethod”方法中调用“WaitOne”方法时至少有一个线程被阻塞,则对“Set”方法的调用(编码在“UnblockAll”方法中)将解除阻塞。因此,在“UnblockAll”方法中的 do..while 语句末尾调用“WaitOne”方法将返回 false。仅当没有线程阻塞时,返回值才为真。

上述推理是否正确,如果正确,该技术是否是处理我的问题的标准方法?我正在尝试主要在 .net compact-framework 2.0 平台上使用该解决方案。

0 投票
3 回答
1798 浏览

c# - 使用等待句柄的条件周期性定时器

我需要一个等效的计时器,它会定期执行一些特定的操作(例如更新数据库中的一些进度或检查要在数据库中执行的新作业)。

这些操作绑定到一个 WaitHandle,它指定是否需要执行作业。所以基本上这可能是,例如,当数据库中有一个新实体并触发对这些新实体的搜索时,从外部设置一个 AutoResetEvent。计时器是必要的,因为我想限制对数据库的查询次数。因此,如果有 10 个新通知到达,则 AutomaticResetEvent 将只设置一次,并且所有这些也只有一个查询。

我的第一次尝试如下所示:

这种方法的问题是 WaitHandle.WaitAny 只会给我触发的第一个 WaitHandle 的索引。因此,如果我有 2 个或更多 WaitHandles 被触发,那么我将只执行第一个操作而不执行其他操作。

您是否有更好的设计来实现执行在指定时间段内触发的所有操作所需的结果?如果它简化了问题,我可以使用另一种通知机制而不是 WaitHandles。

谢谢!