I have a FileSystemWatcher
and the events raised by this when a watched file changes are raised on a different thread from the UI thread. To avoid and cross-thread acess volation fun, I am attempting to use
public void RaisePathChanged(object sender, RenamedEventArgs e)
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
// Some code to handle the file state change here.
}));
}
This compiles fine and the RaisePathChanged
is fired as it should be. However, the code inside the delegate Action(() => { /*Here*/ })
never gets called/invoked, the code is merely skipped.
Why is the code being skipped, how can I fix it and is this the best way to insure code is run on the thread that created it in WPF?
Thanks for your time.
You are mixing up things.
Dispatcher.CurrentDispatcher
is not the same as Application.Current.Dispatcher
.
The second one is the one you seem to be looking for.
Take a look at this.
Dispatcher.CurrentDispatcher vs. Application.Current.Dispatcher
Try it out with application dispatcher.
Dispatcher.CurrentDispatcher
is the dispatcher of the "current" thread - in this case the thread RaisePathChanged
is executing on.
When you say Dispatcher.CurrentDispatcher
.NET will create a new dispatcher if there was none.
It will however not Run()
said dispatcher!
So when you schedule something on it (with BeginInvoke
) it will not actually be executed unless that dispatcher is running.
That likely answers your first question (Why is it not Invoking?)
To avoid cross-thread access violation, you need the dispatcher of the thread that created whatever you are trying to protect and make sure it is a running dispatcher.
If whatever you are trying to protect was created on the default GUI thread, then use Application.Current.Dispatcher
like the previous answer says, otherwise you will need to do a bit more explaining and post a bit more code before we can answer your second question. http://www.diranieh.com/NET_WPF/Threading.htm has a pretty short intro into the subject.