2014-11-23 8 views
-1

Я пытаюсь получить доступ к 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 to static или использовать класс Monitor, но я все равно получаю эту ошибку

ответ

-1

Вы не сказали, что такое сообщение об исключении, но я думаю, что проблема в том, что вы пытаетесь получить доступ к пользовательскому интерфейсу (когда вы добавляете элементы до listBox1) из другой поток. Это не имеет никакого отношения к блокировке; просто для доступа к пользовательскому интерфейсу разрешен только поток пользовательского интерфейса. Если вам нужно сделать это, вы должны выполнить действие в потоке пользовательского интерфейса, используя Invoke:

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

Кроме того, обратите внимание, что замок и вызова действия в потоке пользовательского интерфейса являются дорогостоящими; когда вы обрабатываете события из FileSystemWatcher, вы должны сделать это как можно быстрее, в противном случае существует риск переполнения буфера FileSystemWatcher, и вы пропускаете события. Общий подход - добавить события в потокобезопасную коллекцию в обработчиках событий и обработать их в другом потоке.

+0

Почему downvote? Я сказал что-то не то? –

+0

Спасибо, я попробую (я не нажал downvote) – user3428180

Смежные вопросы