1

所有,我有一个Task在后台线程上运行并做一些繁重的工作。我设置它的方式是,在完成此操作的同时,UI 线程使用进度信息更新 GUI,其中一些使用动画 .gif 文件。看下面的示例代码来说明问题

TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task<bool> task = Task.Factory.StartNew(() => 
{
    // Heavy work.
    if (heavyWorkCompleted)
        MethodToUpdateGui(uiScheduler); // Update DataGridView ImageCell on UI thread
    // More work.
}

在执行“繁重工作”期间,我有一个“进行中”图像显示在相应的 DGV 图像单元格中,如果“繁重工作”成功,则此图像更改为勾号(在 DGV1 中),然后MethodToUpdateGui(uiScheduler)使用此图像(刚刚更改) DGV1 中的图像以更新 DGV2。但是,MethodToUpdateGui(uiScheduler)运行时它有时会太快地更新 DataGridView (DGV2)。我的意思是,图像不是我想要的刻度(应该是由于成功完成)它是“进行中”图像。对于我正在做的事情,似乎 DGV 的更新速度不够快。

有一个更好的方法吗?我敢在 GUI 更新后旋转后台线程以让 DGV1 “赶上”[这很讨厌!]?

谢谢你的时间。

4

1 回答 1

1

有一个更好的方法吗?我敢在 GUI 更新后旋转后台线程以让 DGV1 “赶上”[这很讨厌!]?

这里的问题是 TPL 使用SynchronizationContext.Post将消息发送到 UI 线程。当方法运行时,任务将异步运行,这反过来不会立即更新 GUI。

如果您想确保 GUI 已更新,最简单的选择是MethodToUpdateGui通过等待通过uiScheduler.

这看起来像:

void MethodToUpdateGui(TaskScheduler uiScheduler)
{
    var updateTask = Task.Factory.StartNew( () =>
    {
        // update gui
    }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);

    // Block until Task completes...
    updateTask.Wait();
}

这比尝试旋转要好,因为它会自动阻止并得到 TPL 的通知。

在 Windows 窗体术语中,这实际上是在做Control.Invoke而不是,。Control.BeginInvoke

于 2012-05-22T17:50:43.667 回答