我用相同的代码提出了一个先前的问题,并被建议使用ManualResetEvent
,因为这是做我想做的事情的正确方法,我同意这一点。
问题是:我已经阅读并重新阅读了有关ManualResetEvent
、WaitOne
、和方法的文档和许多教程Set
,但坦率地说,我不太了解它们应该如何使用。Unset
Reset
我的代码做了什么:它一直在寻找连接的设备,当它找到一个时,它会不断验证它是否仍然连接(否则,重新开始寻找)。这是“监控”活动,可以通过客户端代码使用Start
和Stop
方法来启动或停止。还有一个_busy
标志,因此该Stop
方法仅在一个监视周期完成后才返回。
事实是:目前 bool 标志方法不起作用,所以我想用ManualResetEvent
方法替换它,但甚至不知道如何开始。
- 我应该一对一地用 ManualResetEvents 替换标志吗?
- 应该
SearchDevices()
和MonitorDeviceConnection()
方法有条件地在同一个线程中运行,还是应该每个都有(或是)自己的线程? Start
和Stop
(打开和关闭,从客户端代码调用)和两种监视方法之间的“选择”之间的区别如何影响每个 ManualResetEvent 的使用方式?(不太确定这个问题是否有意义)- 使用枚举标志来选择两种可能的执行路径之一是一种代码味道,不是吗?
ManualResetEvent
在“上下文”中摆脱它的明智方法是什么?
这是代码:
public class DeviceMonitor
{
bool _running;
bool _monitoring;
bool _busy = false;
MonitoringMode _monitoringMode;
Thread _monitoringThread;
readonly object _lockObj = new object();
// CONSTRUTOR
public DeviceMonitor()
{
_monitoringThread = new Thread(new ThreadStart(ExecuteMonitoring));
_monitoringThread.IsBackground = true;
_running = true;
_monitoringThread.Start();
}
public void Start()
{
_monitoring = true;
}
public void Stop()
{
_monitoring = false;
while (_busy)
{
Thread.Sleep(5);
}
}
void ExecuteMonitoring()
{
while (_running)
{
Console.WriteLine("ExecuteMonitoring()");
if (_monitoring)
{
lock (_lockObj)
{
_busy = true;
}
Console.WriteLine("busy");
if (_monitoringMode == MonitoringMode.SearchDevices)
{
SearchDevices();
}
else
if (_monitoringMode == MonitoringMode.MonitorDeviceConnection)
{
MonitorDeviceConnection();
}
lock (_lockObj)
{
_busy = false;
}
Console.WriteLine("not busy");
}
Thread.Sleep(1000);
_busy = false;
}
}
private void SearchDevices()
{
var connected = ListDevices();
if (connected.Count > 0)
{
Device = connected.First();
ToggleMonitoringMode();
}
else
Device = null;
}
void MonitorDeviceConnection()
{
if (Device == null)
{
ToggleMonitoringMode();
}
else
{
bool responding = Device.isConnected;
Console.WriteLine("responding " + responding);
if (!responding)
{
Device = null;
ToggleMonitoringMode();
}
}
}
void ToggleMonitoringMode()
{
if (_monitoringMode == MonitoringMode.SearchDevices)
_monitoringMode = MonitoringMode.MonitorDeviceConnection;
else
if (_monitoringMode == MonitoringMode.MonitorDeviceConnection)
_monitoringMode = MonitoringMode.SearchDevices;
}
enum MonitoringMode
{
SearchDevices,
MonitorDeviceConnection
}
}