-1

I'm trying to access the ListBox from two threads. I am using two lock statements but this doesn't work.

My code:

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

I don't know why it doesn't work (i have two lock statements), but i am getting error: invalidoperationexception was unhandled

I tried to change lockObj to static or use Monitor class but i it still get this same error

1 Answers1

-1

You didn't say what the exception message was, but I think the problem is that you're trying to access the UI (when you add items to listBox1) from another thread. It has nothing to do with locking; it's just that only the UI thread is allowed to access the UI. If you need to do that, you must execute the action on the UI thread, using Invoke:

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

Also, note that locking and invoking an action on the UI thread are expensive; when you process events from the FileSystemWatcher, you must do it as fast as possible, otherwise there's a risk that the FileSystemWatcher's buffer overflows and you miss events. A common approach is to append the events to a thread-safe collection in the event handlers, and process them on another thread.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758