1

I have the following code:

private void WatchFileForChanges()
{
    if (fileInfo.Directory != null)
    {
        _watcher = new FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name);
        _watcher.NotifyFilter = NotifyFilters.LastWrite;
        _watcher.Changed += OnFinalBuilderStatusChanged;
        _watcher.EnableRaisingEvents = true;
    }
}

private void OnChanged(object source, FileSystemEventArgs e)
{
    lock (this)
    {
       // here i see 2 different threads coexist
       // even there is a lock!!
       DispatchResult();
    }
}

as can be sing in the comment, i am seeing to different threads co-exist in the OnChanged even there is a lock mechanism, how come??

sll
  • 61,540
  • 22
  • 104
  • 156
user829174
  • 6,132
  • 24
  • 75
  • 125
  • Do you realise the implications of [`lock`ing on `this`](http://stackoverflow.com/questions/251391/why-is-lockthis-bad)? – Grant Thomas Mar 27 '12 at 15:46
  • thanks for your answer, but still, why does the 2 threads passed the lock? – user829174 Mar 27 '12 at 15:49
  • @user829174 Two threads can go through the lock, but not at the same time... That's all a lock does. – Reed Copsey Mar 27 '12 at 15:51
  • What makes you think two threads are inside the lock at the same time? And are you sure `this` is referencing the same instance? In other words, is there more than one instance of this class in play? – Brian Gideon Mar 27 '12 at 16:17
  • Brian, there is more than one instance of this class, how can i tell on which instance i am? – user829174 Mar 27 '12 at 20:34

1 Answers1

2

lock does not cause the thread being used to change. I merely prevents multiple threads from accessing the code within that block at the same time.

The reason you're getting multiple threads here is that FileSystemWatcher raises its Changed event on a threadpool thread.

If you want to have DispatchResult occur on a single thread, you'll need to use some form of SynchronizationContext to push the result back onto that thread. In a UI application, this is typically done via Control.Invoke or Dispatcher.Invoke, for example.

On a side note, it's a good idea to avoid using lock(this), and instead make a private object that's used just for your locking. Otherwise, another object could lock on your same instance and cause all sorts of issues.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373