.net EventWaitHandle-多线程=行为不一致
我正在尝试使用一个设备设置一些通信,您可以在其中发送命令并接收响应。但是,我确实希望确保控制超时标志以防止无限等待时间 我是这样做的:.net EventWaitHandle-多线程=行为不一致,.net,multithreading,event-wait-handle,.net,Multithreading,Event Wait Handle,我正在尝试使用一个设备设置一些通信,您可以在其中发送命令并接收响应。但是,我确实希望确保控制超时标志以防止无限等待时间 我是这样做的: private volatile EventWaitHandle _signal; public void Send() { // Do something _signal.WaitOne(30000); // Continue with something else _signal.Reset(); } public
private volatile EventWaitHandle _signal;
public void Send()
{
// Do something
_signal.WaitOne(30000);
// Continue with something else
_signal.Reset();
}
public void Receive()
{
_signal.Set();
}
我的问题是,如果我有多个线程(本例中为2个线程)可以访问Send方法和以下场景:
线程A:
// Sends a "listen" command, but no response is received
Send();
线程B:
// Sends a "cancel" command and response (success) is received
Send();
我得到了不一致的结果,也就是说,有时当我得到第二个命令(cancel)的响应时,两个线程都会继续,我可以理解,但有时第一个线程会达到30000ms超时,这我无法解释
关于我遗漏了什么和/或做错了什么,有什么建议吗?这里的EventWaitHandle不是合适的同步对象。您需要,这样只有一个线程可以处于发送命令并等待响应的状态。换句话说,线程必须严格轮流与设备通信 ManualResetEvent并不能保证这一点,只要调用Set(),那么所有在WaitOne()调用上阻塞的线程都将被解除阻塞。如果不止一个线程,那么当两个或多个线程试图同时发送命令时,程序将出现故障
互斥提供互斥。这就是它的名称。这里的EventWaitHandle不是合适的同步对象。您需要,这样只有一个线程可以处于发送命令并等待响应的状态。换句话说,线程必须严格轮流与设备通信 ManualResetEvent并不能保证这一点,只要调用Set(),那么所有在WaitOne()调用上阻塞的线程都将被解除阻塞。如果不止一个线程,那么当两个或多个线程试图同时发送命令时,程序将出现故障
互斥提供互斥。这就是它的名称。这里的EventWaitHandle不是合适的同步对象。您需要,这样只有一个线程可以处于发送命令并等待响应的状态。换句话说,线程必须严格轮流与设备通信 ManualResetEvent并不能保证这一点,只要调用Set(),那么所有在WaitOne()调用上阻塞的线程都将被解除阻塞。如果不止一个线程,那么当两个或多个线程试图同时发送命令时,程序将出现故障
互斥提供互斥。这就是它的名称。这里的EventWaitHandle不是合适的同步对象。您需要,这样只有一个线程可以处于发送命令并等待响应的状态。换句话说,线程必须严格轮流与设备通信 ManualResetEvent并不能保证这一点,只要调用Set(),那么所有在WaitOne()调用上阻塞的线程都将被解除阻塞。如果不止一个线程,那么当两个或多个线程试图同时发送命令时,程序将出现故障
互斥提供互斥。这就是它的名字。你不是在使用
AutoResetEvent
?您需要使用ManualResetEvent
,否则它将在等待线程发出信号时自动重置。事实上,您可能根本不想使用等待句柄。对于您正在尝试做的事情,很可能有更好的解决方案,特别是如果您有能力使用.NET4.5.1。为什么首先是多线程的?使用ManualResetEvent和多线程来取消挂起的响应,即发送命令,但我需要能够在收到响应之前取消它。(不幸的是,仅限于.Net 4.0)。Net 4.0应该仍然足以使您能够使用异步I/O,尽管4.5使这更容易。您不是在使用AutoResetEvent
?您需要使用ManualResetEvent
,否则它将在等待线程发出信号时自动重置。事实上,您可能根本不想使用等待句柄。对于您正在尝试做的事情,很可能有更好的解决方案,特别是如果您有能力使用.NET4.5.1。为什么首先是多线程的?使用ManualResetEvent和多线程来取消挂起的响应,即发送命令,但我需要能够在收到响应之前取消它。(不幸的是,仅限于.Net 4.0)。Net 4.0应该仍然足以使您能够使用异步I/O,尽管4.5使这更容易。您不是在使用AutoResetEvent
?您需要使用ManualResetEvent
,否则它将在等待线程发出信号时自动重置。事实上,您可能根本不想使用等待句柄。对于您正在尝试做的事情,很可能有更好的解决方案,特别是如果您有能力使用.NET4.5.1。为什么首先是多线程的?使用ManualResetEvent和多线程来取消挂起的响应,即发送命令,但我需要能够在收到响应之前取消它。(不幸的是,仅限于.Net 4.0)。Net 4.0应该仍然足以使您能够使用异步I/O,尽管4.5使这更容易。您不是在使用AutoResetEvent
?您需要使用ManualResetEvent
,否则它将在等待线程发出信号时自动重置。事实上,您可能根本不想使用等待句柄。对于您正在尝试做的事情,很可能有更好的解决方案,特别是如果您有能力使用.NET4.5.1。为什么首先是多线程的?使用ManualResetEvent和多线程来取消挂起的响应,我