2014-11-23 109 views
-1

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

我的代码:

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静态或使用监视器类,但我仍然得到这个相同的错误

回答

-1

你没有说异常的消息是什么,但我认为问题是,你试图访问UI(当你添加项目到listBox1)从另一个线程。它与锁定无关;只是只允许UI线程访问UI。此外

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

,注意锁定和调用UI线程上的操作是昂贵的,如果你需要做的是,必须在UI线程上执行的动作,用Invoke当您处理来自FileSystemWatcher的事件时,必须尽可能快地完成,否则可能会导致FileSystemWatcher的缓冲区溢出并且您错过了事件。常见的方法是将事件附加到事件处理程序中的线程安全集合,并在另一个线程上处理它们。

+0

为什么downvote?我说错什么了吗? – 2014-11-23 01:06:23

+0

谢谢,我会试试看(我没有点击downvote) – user3428180 2014-11-23 01:10:39