线程似乎停止运行时,我调用一个给定的方法在同一类,为什么

本文关键字:一类 为什么 方法 运行时 线程 调用 一个 | 更新日期: 2023-09-27 18:11:02

我有一个类,不断刷新设备物理连接到PC通过USB。监视方法运行在检查_monitoring标志的线程上,StartStop方法只是设置和取消该标志。

我目前的问题是:当线程运行时,我得到预期的"忙"answers"不忙"控制台打印,但是当我调用Stop方法时,它永远保持运行while(_busy),因为不知怎的 _monitoringThread似乎停止运行!

我怀疑它停止运行是因为最后一次打印总是busy,也就是说,ExecuteMonitoring在中途运行,然后没有人知道(至少我不知道)。

暂停调试并查看StackTrace也没有帮助,因为它永远保留在Stop()方法中的while(_busy)语句中。

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
    }
}    

线程似乎停止运行时,我调用一个给定的方法在同一类,为什么

最可能的解释是:优化:编译器看到_busyStop方法中从未更改,因此允许通过用true替换_busy将其转换为无限循环。这是有效的,因为_busy字段没有被标记为易失性,因此优化器不必假设在另一个线程上发生了更改。

因此,尝试将_busy标记为易失性。或者,甚至更好——实际上要好得多——使用ManualResetEvent:

ManualResetEvent _stopMonitoring = new ManualResetEvent(false);
ManualResetEvent _monitoringStopped = new ManualResetEvent(false);
ManualResetEvent _stopRunning = new ManualResetEvent(false);
public void Stop()
{
    _stopMonitoring.Set();
    _monitoringStopped.Wait();
}
void ExecuteMonitoring()
{
    while (!_stopRunning.Wait(0))
    {
        Console.WriteLine("ExecuteMonitoring()");
        if(!_stopMonitoring.Wait(0))
        {
            _monitoringStopped.Unset();
            // ...
        }
        _monitoringStopped.Set();
        Thread.Sleep(1000);
    }
}

代码来自内存,可能包含一些拼写错误。