gpt4 book ai didi

c# - 在任务中,为什么 IProgress 在 UI 线程中正确执行而不是 Action

转载 作者:太空狗 更新时间:2023-10-30 00:24:47 26 4
gpt4 key购买 nike

在下面的代码中:

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;
}

如果我不包含 actionDispatcher.BeginInvoke它将提示 调用线程无法访问此对象,因为另一个线程拥有它。 而对于 progress没有必要这样做。

怎么会IProgress<T>无需 Dispatcher.BeginInvoke 即可工作?

最佳答案

因为在内部 Progress 存储了对构造时 SynchronizationContext.Current 中内容的引用,并在报告进度时将事件触发到该上下文。

它专门设计用于从非 UI 线程更新 UI。如果它不这样做,就没有那么多理由使用它,也根本不难做到。

这是我在 .NET 4.5 之前用作 Progress 实现的内容。它不会与 .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);
}
}
}

关于c# - 在任务中,为什么 IProgress<T> 在 UI 线程中正确执行而不是 Action<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21835115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com