ʞᴉɯ*_*ʞᴉɯ 3 .net c# async-await
我正在使用基于任务的异步模式 (TAP)来完成一些长任务,IProgress<T>用于向主 UI 报告进度。在Progress.Report似乎只有当它被其他的await任务之前工作。例如,如果我在内联 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;
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以强制同步发布报告消息吗?谢谢。
Progress.Report 似乎只有在它之前有另一个等待任务时才起作用。
那讲得通。一旦您调用该方法,就会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);
}
}
Run Code Online (Sandbox Code Playgroud)
为了保持响应,您可以将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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1360 次 |
| 最近记录: |