On the following piece of code :
Task UpdateMedias<TProperty>(Expression<Func<Media, TProperty>> property, Func<Media, TProperty> func)
{
var medias = GetSelectedMedias().ToList();
IProgress<double> progress = new Progress<double>(d => barQueueProgress.EditValue = d);
Action<Media, Expression<Func<Media, TProperty>>, Func<Media, TProperty>> action =
(media, expression, arg3) => UpdateMedia(media, expression, arg3);
Task task = Task.Run(() =>
{
var i = 0;
foreach (var media in medias)
{
progress.Report(1.0d / medias.Count * ++i);
action(media, property, func);
}
});
Task with = task.ContinueWith(s =>
{
progress.Report(0.0d);
GridControl1.RefreshData();
});
return with;
}
If I don't encompass action
with Dispatcher.BeginInvoke
it will complain with The calling thread cannot access this object because a different thread owns it. while for progress
there is no need to do so.
How come IProgress<T>
works without the need of Dispatcher.BeginInvoke
?
Because internally Progress
stores a reference to what was in SynchronizationContext.Current
when it was constructed, and it fires the event to that context when reporting progress.
It was specifically designed for updating the UI from a non-UI thread. If it didn't do this, there wouldn't be nearly as much reason to use it, nor is it hard at all to do.
Here is what I use as an implementation of Progress
pre .NET 4.5. It won't be identical to the .NET implementation, but it'll give you a pretty good idea of what's going on:
public interface IProgress<T>
{
void Report(T data);
}
public class Progress<T> : IProgress<T>
{
SynchronizationContext context;
public Progress()
{
context = SynchronizationContext.Current
?? new SynchronizationContext();
}
public Progress(Action<T> action)
: this()
{
ProgressReported += action;
}
public event Action<T> ProgressReported;
void IProgress<T>.Report(T data)
{
var action = ProgressReported;
if (action != null)
{
context.Post(arg => action((T)arg), data);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With