问题标签 [manualresetevent]

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 投票
0 回答
405 浏览

c# - 如何在多线程中释放线程?

如题,多线程需要如何释放线程?例如:我有 5 个线程正在等待。我只想释放线程位置 3 我使用 autoresetevent/manualresetevent/monitor.wait 和 monitor.pulse 但所有释放线程都遵循 FIFO 帮助我!!!

更新:这是form1:

表格2:

PS:Form1有1个按钮来启动多个backgroundworker并显示form2,然后所有backgroundworker等待从form2获取文本框的文本验证码,当用户输入backgroundworker的文本显示在form2上时,只有backgroundworker被释放。所有其他后台工作人员仍在等待

0 投票
1 回答
3253 浏览

c# - 跨线程退出/取消 while 循环的技术:bool、ManualResetEvent 或 CancellationToken

我正在编写一个有几个线程的程序,每个线程都有一个 while 循环,直到用户指定它应该停止。我想到了几种退出循环的方法,然后是线程,并在下面概述了这些方法。

问题

  1. 每个都有优点和缺点吗?
  2. 是否存在您会使用一种而不使用另一种的情况?
  3. 我听说有些人说他们更喜欢 CancellationTokens 来退出线程。与其他两种方法相比,这种方法有什么吸引力?

下面是方法。

bool方法_

最初,我声明了一个 bool 并声明循环一直运行,直到用户将 bool 设置为 false: while(running) { Thread.Sleep(10); /*do work*/ }。然后我思考这是否完全是线程安全的。如果编译器做了一些优化并将 bool 移动到寄存器会怎样。在这种情况下,线程将看到不同的布尔值。结果,我用volatile关键字标记了 bool 以避免编译器优化。

ManualResetEvent方法_

我的下一个方法是创建一个ManualResetEvent,然后说 bool 在 WaitOne() 为 false 时运行:while(!mre.WaitOne(10)) {/*do work*/}。这将阻塞 10 毫秒,然后运行循环,一遍又一遍,直到我们这样做mre.Set()并且循环退出。

CancellationToken方法_

这种方法我还没有真正尝试过,但我读过几个人们更喜欢用这种方式取消线程的地方。它显然是线程安全的。可以定义 a CancellationTokenSource,调用它cts,然后传递cts.Token给新线程运行的方法,并使用 if 语句检查是否已请求取消:while(!token.IsCancellationRequested) { Thread.Sleep(10); /*do work*/ }

更新 1:

我发现了一个类似的帖子,得出的结论是该MRE方法比该CancellationToken方法慢得多。有关完整信息,请参阅此处:停止线程、ManualResetEvent、volatile boolean 或 cancelToken

更新 2:

在将bool方法与其他两种方法进行比较时,Eric Lippert 在这里有一个很好的答案:AutoResetEvent vs. boolean to stop a thread

更新 3:

我找到了另一个相关的信息。CancellationTokens 一旦被取消就不能被重置。因此,当您只想暂时取消循环以稍后重新启动时,它并不理想。为此,MRE 可能会更好(您可以随心所欲地设置和重置)。

0 投票
1 回答
190 浏览

c# - 在诸如 ManualResetEvent 之类的同步构造上等待的可更新(可重置)超时

这是问题的描述:

我需要同步 API 调用。为了使这个调用同步,我定义了一个 ManualResetEvent 并在它上面调用了 WaitOne。在调用外部 COM 对象之后调用 WaitOne。在某些情况下,它永远不会返回。这就是为什么我必须为那个 Wait 调用定义一个超时。但是,我不能将常量传递给 Wait 方法,因为如果调用成功,则此 API 从 COM 对象接收事件并且在事件的每个处理程序中,传递给 WaitOne 的超时应该被重置。

考虑这个例子:

我只是想知道是否有人遇到过这个问题。我相信这应该是一种常见的情况。据我了解,没有“开箱即用”的解决方案。所以我必须建立自己的同步原语,或者也许有人已经做到了?

更新。 我想要这样的东西(由我自己实现):

0 投票
0 回答
640 浏览

c# - 用于 Unity3D 的 dll 中的 ManualResetEvent

我有一个 C# 类库 (.Net 3.5) 编译为 dll 并导入到 Unity3D。在某些方法中,我必须在继续主进程之前等待主线程。所以我使用 ManualResetEvent 对象在超时前等待指定的持续时间。但在 Unity3D 中它不起作用。它不是在等待定义的时间。当尝试使用 ManualResetEventSlim 时,也会发生同样的情况。

有没有人知道阻塞主线程的替代方法?我已经尝试过使用 DateTime 的 Thread.Sleep() 和 while-loop,但在这两种情况下,Unity 在我开始播放模式之前就已经崩溃了。

编辑:

发布一些代码很困难,我将尝试解释。我想在 WPF 应用程序和 Unity3D 之间建立网络连接。当客户端向服务器发送请求,例如接收对象列表时,需要等待才能说再见。这只是摘录。messenger 对象发送消息。然后将调用 ManualResetEvent(它在属性 WaitEvent 中)。超时后,我查看哪个状态有我的等待消息。每个等待模式都会引发异常或返回响应。

如果没有 Unity3D,它可以毫无问题地工作,所以它应该。直到现在我都认为,Unity 可以使用 .Net 3.5。但是当我不得不使用 .Net 2.0 时,我必须做更多的改变。你知道我在哪里可以获得 .Net 2.0 的 System.Threading.dll 吗?

谢谢你的帮助。

可能的解决方案:

我没有调用WaitOne ,而是调用了一个委托。这将在库之外设置,我为此使用了一个属性。

在 dll 中:

在 Unity3D 中:

我知道,这是一个肮脏的黑客,它不像我计划的那样工作。另外我不得不说:Unity3D 在我测试时非常不稳定。但也许有一天,有人会有更好的想法或解决方案。

0 投票
1 回答
895 浏览

c# - 如何正确使用 Async、Await 和 ManualResetEvents 来控制无限循环

所以我在这里要做的是:

  1. 如果队列不为空,则使引擎循环并处理对象。
  2. 如果队列为空,我调用 manualresetevent 使线程休眠。
  3. 当添加一个项目并且循环未激活时,我设置了手动重置事件。
  4. 为了让它更快,我从列表中选择最多 5 个项目并异步对它们执行操作并等待它们全部完成。

问题:

  1. 只要调用了对 AddToUpdateQueueMethod 的新调用,就会调用这两个列表上的 clear 方法。
  2. 在我等待 Task.WhenAll(tasks) 的时候,在我的脑海中,所以线程应该在继续之前等待它的完成,因此只有在 Task.WhenAll(tasks) 返回之后才应该调用列表中的清除。

我在这里缺少什么,或者实现这一目标的更好方法。

0 投票
1 回答
513 浏览

c++ - 使用 ManualResetEvent c++/cli 等待 DownloadFileAsync

我在使用 Windows 窗体应用程序的 C++/CLI 中遇到了一些令人沮丧的问题。

所以问题是我必须使用 WebClient istance 从网络服务器下载文件。通常我使用 DownloadFile 而不是 DownoadFileAsyn,但如果我想显示一个显示下载文件进度的进度条,我必须使用 DownloadFileAsyn。那么我怎么能等到下载完成呢?

代码是:

因此,当下载完成时,程序停止运行,并且在 mre->WaitOne() 指令之后不会运行上面编写的指令块。DownloadFileCompleted() 没有执行,实际上甚至显示了消息框。

有任何想法吗?我已经搜索过这个问题,很多人都遇到过,但仅限于 c#。而且我刚刚将解决方案从c#“翻译”到c++。但它不起作用...

0 投票
3 回答
507 浏览

c# - ManualResetEvent 不等待线程池完成

我有要处理的批次列表。永远。
我想并行执行每个块(5),并在完成后移至下一个块。
出于某种原因,下面的代码不会等待块完成并继续,即使它没有完成。

0 投票
1 回答
697 浏览

c# - C# 在 Task.WhenAll() 中引发事件

我有一个生产者-消费者乘法任务类。我有一个方法:

有一个启动方法:

问题是DoneEvent被触发,但订阅者事件处理程序从未被执行。我成功运行事件处理程序的唯一方法是我将 Run 方法设置为async并在await before 之前添加Task.WhenAll(..)。但随后又提出了另一个问题。在方法Consume()中,我有一个ManualResetEvent PauseBlock. 当它被重置时,主线程也会等待。

提前谢谢。

编辑: 我已经成功地做到了(两天后)我改变了一点 Run 方法:

现在它工作正常。仅供参考消费者方法:

谢谢大家。如果您对 ow 有任何改进建议,我希望看到它。

0 投票
2 回答
551 浏览

c# - 同一方法中的多个异步调用。正确的方式?

我需要从 IP 地址提供商 URL 之一获取我的公共 IP 地址。问题是这些服务不可靠,所以我必须回退到不同的 URL。为了获得最大的性能,我想同时向所有服务提供者发起 WebRequest,并考虑第一个回复的结果。

这是我写的代码。它工作得很好。但是我用过EventWaitHandle。我只想知道这是否是正确的方法,或者是否可以在不使用WaitHandle(仅使用 async/await)的情况下做同样的事情?

这是 MyResetEvent 类:

0 投票
2 回答
623 浏览

c# - ManualResetEvent.WaitOne() 抛出 NullReferenceException:对象引用未设置为对象的实例

在处理 ManualResetEvent.WaitOne() 时,我遇到了一个奇怪的随机 NPE 错误。这是我的代码。

我有一个方法可以创建 ManualResetEvent 对象,然后将其作为依赖参数 (manualResetEvent) 之一传递给 Windows Workflow Foundation (WWF) 工作流实例,然后我进入 manualResetEvent.WaitOne() API。

当工作在 WWF 内完成时,我只需调用 manualResetEvent.set()。

所有这些都编译得很好,并且在运行时,我看到流程按预期进入了 WWF,并且调用者也确实在等待 WaitOne() 调用。

WWF 调用 manualResetEvent.Set() 通知调用者的那一刻,我看到调用者不是 WWF 的 NPE 异常。

System.NullReferenceException:对象引用未设置为对象的实例。

我真的不知道这个异常是从哪里来的。当我在 VS IDE 中调试此代码时,一切正常,但只有当应用程序处于发布模式时,我才会看到此异常。

我在这里做错了什么?