I have a class that constantly refreshes devices physically connected to PC via USB. The monitoring method runs on a thread checking a _monitoring
flag, and Start
and Stop
methods just set and unset that flag.
My current problem is: when the thread is running, I get the expected "busy" and "not busy" console prints, but when I call Stop
method, it keeps running while(_busy)
forever, because somehow the _monitoringThread
seems to stop running!
I suspect it stops running because the last print is always busy
, that is, the ExecuteMonitoring
runs midway and then nobody knows (at least I don't).
Pause debugging and looking at StackTrace didn't help either, because it keeps in the while(_busy)
statement inside Stop()
method, forever.
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
}
}