我有一个.NET Windows表单,它创建了一个异步运行的任务。该任务应该调用以更新其进度的UI。它可以工作,但是进度条只会延迟更新。
public partial class WaitDialog : Form
{
private readonly TaskScheduler _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
private void ReportViewerWaitForm_Load(object sender, EventArgs e)
{
_asyncTask = Task.Factory.StartNew(Calculate(), _cancellationTokenSource.Token);
_asyncTask.ContinueWith(task => Close(), CancellationToken.None, TaskContinuationOptions.None, _uiScheduler);
}
private void Calculate()
{
UpdateProgressCount(0, 1000);
for (int i = 0; i < 1000; i++)
{
// do some heavy work here
UpdateProgressCount(i);
}
}
private void UpdateUserInterface(Action action)
{
Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, _uiScheduler).Wait();
}
public void UpdateProgressCount(int count)
{
UpdateUserInterface(() => progressBar.Value = count);
}
public void UpdateProgressCount(int count, int total)
{
UpdateUserInterface(() =>
{
progressBar.Minimum = 0;
progressBar.Maximum = total;
});
UpdateProgressCount(count);
}
private void WaitForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (!_asyncTask.IsCompleted)
{
e.Cancel = true;
}
}
}
进度条被正确设置,当表单关闭时,其值被设为1000(或100%),但在UI上并未以此方式显示,它仅显示大约50%的完成情况。
更新UI的任务已启动,然后调用了Wait()函数,但异步任务似乎在更新UI之前继续运行。我猜这是因为UI线程本身进行了某种BeginInvoke()来更新UI。
最终,当异步(重型工作)任务完成时,UI没有完全更新,表单关闭了。但是UI任务中的Wait()、Application.DoEvents()或progressBar.Update()都没有任何效果,不能允许在返回到重型工作任务之前更新UI。