gpt4 book ai didi

c# - 强制异步等待 IProgress.Report() 同步

转载 作者:行者123 更新时间:2023-12-04 01:58:19 25 4
gpt4 key购买 nike

我正在使用基于任务的异步模式 (TAP) 执行一些长任务,使用 IProgress<T>向主 UI 报告进度。Progress.Report似乎只有在它之前有另一个等待任务时才有效。例如,如果我在内联 for 循环中使用,则报告消息仅在任务结束时发布:

public async Task<bool> DoSomething(IProgress<string> progress)
{
progress.Report("Start"); // works
await SomeTask();

progress.Report("Message 1"); // works ONLY at end

for ()
{
progress.Report("Message x"); // works ONLY at end
// do some tasks inline
}

return true;
}

有什么方法可以强制同步发布报告消息吗?谢谢。

最佳答案

The Progress.Report seems to work only if it is preceded by another await task.

这是有道理的。 Progress<T>捕获 SynchronizationContext并在您调用 Report 后发布到它方法。如果你的异步方法不是真正的异步并且大部分 CPU 工作是在 UI 线程上完成的,那么你就不会释放消息循环来处理更多事件,因此你只会看到它在结束时更新方法调用。

这就是Progress<T>.Report已实现:

protected virtual void OnReport(T value)
{
// If there's no handler, don't bother going through the [....] context.
// Inside the callback, we'll need to check again, in case
// an event handler is removed between now and then.
Action<T> handler = m_handler;
EventHandler<T> changedEvent = ProgressChanged;
if (handler != null || changedEvent != null)
{
// Post the processing to the [....] context.
// (If T is a value type, it will get boxed here.)
m_synchronizationContext.Post(m_invokeHandlers, value);
}
}

为了保持响应,您可以卸载 for循环到线程池线程:

public async Task<bool> DoSomethingAsync(IProgress<string> progress)
{
progress.Report("Start"); // works
await SomeTask();
progress.Report("Message 1");

await Task.Run(() =>
{
progress.Report("Message x");
// Do more CPU bound work
}
return true;
}

关于c# - 强制异步等待 IProgress<T>.Report() 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34051252/

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