Ayb*_*ybe 4 c# multithreading task dispatcher
在下面的代码中:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果我不包括action与Dispatcher.BeginInvoke它会与抱怨调用线程,因为不同的线程拥有它不能访问该对象.而progress没有必要这样做.
怎么IProgress<T>没有需要的工作Dispatcher.BeginInvoke?
因为内部Progress存储对SynchronizationContext.Current构造时的内容的引用,并且在报告进度时将事件触发到该上下文.
它专门用于从非UI线程更新UI.如果它没有这样做,就没有那么多理由使用它,也不是很难做到.
这是我用作Progress.NET 4.5之前的实现.它与.NET实现不同,但它会让你很好地了解正在发生的事情:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
599 次 |
| 最近记录: |