C# 强制异步等待IProgress<;T>;。要同步的报表()
我正在使用基于任务的异步模式(TAP)执行一些长任务,使用C# 强制异步等待IProgress<;T>;。要同步的报表(),c#,.net,async-await,C#,.net,Async Await,我正在使用基于任务的异步模式(TAP)执行一些长任务,使用IProgress向主UI报告进度。 Progress.Report似乎只有在前面有另一个等待任务时才起作用。 例如,如果在内联for循环中使用,则报告消息仅在任务结束时发布: public async Task<bool> DoSomething(IProgress<string> progress) { progress.Report("Start"); // works await Some
IProgress
向主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;
}
公共异步任务DoSomething(IProgress progress)
{
progress.Report(“Start”);//有效
等待某项任务();
progress.Report(“Message 1”);//只在末尾起作用
对于()
{
progress.Report(“Message x”);//只在末尾起作用
//在线执行一些任务
}
返回true;
}
有没有办法强制同步发布报告消息?
谢谢
只有在前面有另一个等待任务的情况下,Progress.Report似乎才起作用
这是有道理的<代码>进度捕获同步上下文
并在调用报告
方法后发布到该上下文。如果您是异步的,那么这个方法并不是真正的异步的,并且大部分CPU工作都是在UI线程上完成的,那么您并没有释放消息循环来处理更多的事件,因此您只看到它在方法调用结束时更新
这就是进度报告的实现方式:
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);
}
}
“仅在结束时工作”是什么意思?如果您希望
SomeTask
报告进度,那么它应该有一个IProgress
参数,并通过progress正常报告进度。报告
,因此我需要调用for循环来报告其他等待任务?@kim您需要释放UI线程以允许其更新。如果您实际上没有任何异步工作要做,您可以使用任务在线程池线程上执行其他CPU限制的工作。运行,这样您就不会冻结for
循环为非阻塞的UIT了?谢谢。任务。运行是解决方案。
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;
}