多个线程访问变量

时间:2014-11-23 00:56:52

标签: c# multithreading variables

我试图从两个线程访问ListBox。我使用两个锁定语句,但这不起作用。

我的代码:

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

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

我尝试将lockObj更改为静态或使用Monitor类,但我仍然得到同样的错误

1 个答案:

答案 0 :(得分:-1)

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

在UI线程上执行操作
this.Invoke(new Action(() => listBox1.Items.Add(logInfo.ToString())));

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