多线程访问变量

本文关键字:变量 访问 多线程 | 更新日期: 2023-09-27 18:31:29

我正在尝试从两个线程访问列表框。我正在使用两个锁定语句,但这不起作用。

我的代码:

   public partial class Form1 : Form
   {
        private List<LogInfo> logs = new List<LogInfo>();
        private static Object lockObj = new Object();
        private static Object lockObj0 = new Object();
        /* ... */
        void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
        {
            try
            {
                ToggleWatcher(false);
                LogInfo logInfo = new LogInfo(e.ChangeType, GetCurrentTime(), e.FullPath, e.OldName, e.Name);
                lock (lockObj)
                {
                    logs.Add(logInfo);
                    listBox1.Items.Add(logInfo.ToString());
                }
            }
            finally
            {
                ToggleWatcher(true);
            }
        }
        void fileSystemWatcher_Detect(object sender, FileSystemEventArgs e)
        {
            try
            {
                ToggleWatcher(false);
                LogInfo logInfo = new LogInfo(e.ChangeType, GetCurrentTime(), e.FullPath);
                lock (lockObj)
                {
                    logs.Add(logInfo);

                    // Here in below line i get error: invalidoperationexception was unhandled
                    listBox1.Items.Add(logInfo.ToString());
                }
            }
            finally
            {
                ToggleWatcher(true);
            }
        }
    }

我不知道为什么它不起作用(我有两个锁定语句),但是我收到错误:无效操作异常未处理

我试图将 lockObj 更改为静态或使用监视器类,但我仍然收到同样的错误

多线程访问变量

您没有说异常消息是什么,但我认为问题是您正在尝试从另一个线程访问 UI(当您将项目添加到listBox1时)。它与锁定无关;只是只允许 UI 线程访问 UI。如果需要执行此操作,则必须使用 Invoke 在 UI 线程上执行操作:

this.Invoke(new Action(() => listBox1.Items.Add(logInfo.ToString())));

另外,请注意,锁定和调用 UI 线程上的操作是昂贵的;当您处理来自FileSystemWatcher的事件时,您必须尽快完成,否则存在FileSystemWatcher缓冲区溢出和您错过事件的风险。一种常见的方法是将事件追加到事件处理程序中的线程安全集合,并在另一个线程上处理它们。