My WPF application launches long running functions on background threads, typically via a button click/command, e.g.
StartCommand = new RelayCommand(async o => await StartAsync(), o => true);
...
private async Task StartAsync()
{
await Task.Run(() => LongRunningFunction());
}
These long running functions raise various events to report progress to the user, update UI values, etc. The view-model handles such events and updates bound properties, e.g.:
private void LongRunningProcessProgressChanged(object sender, ProgressEventArgs e)
{
StatusMessageText = string.Format("Progress {0}%", e.Progress);
}
Most of the time this works fine but occasionally I get the usual exception about updating the UI from a background thread ("The calling thread cannot access this object because a different thread owns it")), so I have to wrap the code in a Dispatcher.Invoke(...)
. I haven't really spotted a pattern as to when I do or don't have to do this, so can anyone shed some light on it?
To be honest I'm surprised that the above code works at all. A breakpoint confirms that these event handlers run on a worker thread, not the UI thread, so why don't I see the exception all the time? Is it something to do with the type of property being updated?
Edit People are proposing answers to a problem which I am already aware of. Reading my question again I might have confused readers with the part "Most of the time this works fine but occasionally I get the usual exception". I didn't mean that it's an intermittent problem - what I really meant was that some of my VMs don't have a problem updating bound properties within their respective progress event handler, while other VMs do. I suspect it has something to do with the property type, e.g. updating a string property works but not an ObservableCollection.
My question was more of a curiosity thing, i.e. why some bound properties are okay with being updated from a b/g thread while others aren't.