使用 TaskScheduler.FromCurrentSynchronizationContext 更新 Task 中的 UI [英] update UI in Task using TaskScheduler.FromCurrentSynchronizationContext

查看:17
本文介绍了使用 TaskScheduler.FromCurrentSynchronizationContext 更新 Task 中的 UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Task 向列表框添加一些文本,我只需使用一个按钮并将此代码放置在点击事件中:

I want to add some text to list box using Task and I simply use a button and place in click event this code:

TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
    for (int i = 0; i < 10; i++)
    {
        listBox1.Items.Add("Number cities in problem = " + i.ToString());
        System.Threading.Thread.Sleep(1000);
    }
}, CancellationToken.None, TaskCreationOptions.None, uiScheduler);

但它不起作用并且 UI 在 for 循环结束之前被锁定.

but it does not work and UI locked until the end of the for loop.

问题出在哪里?

谢谢:)

推荐答案

问题出在哪里?

好吧,您明确表示要在 UI 线程中执行任务...然后您在任务中休眠,因此它阻塞了 UI 线程.您如何期望在 UI 线程中,但 Thread.Sleep 不会 导致问题?

Well you're explicitly saying that you want to execute the task in the UI thread... and then you're sleeping within the task, so it's blocking the UI thread. How did you expect to be in the UI thread, but for Thread.Sleep not to cause a problem?

如果您可以使用 C# 5 和 async/await,那会使事情变得更容易:

If you can use C# 5 and async/await, that would make things much easier:

private static async Task ShowCitiesAsync()
{
    for (int i = 0; i < 10; i++)
    {
        listBox1.Items.Add("Number cities in problem = " + i);
        await Task.Delay(1000);
    }
}

如果您不能使用 C# 5(如您的标签所建议的那样),那将非常棘手.您最好使用 Timer:

If you can't use C# 5 (as suggested by your tags), it's significantly trickier. You might be best off using a Timer:

// Note: you probably want System.Windows.Forms.Timer, so that it
// will automatically fire on the UI thread.
Timer timer = new Timer { Interval = 1000; }
int i = 0;
timer.Tick += delegate
{
    listBox1.Items.Add("Number cities in problem = " + i);
    i++;
    if (i == 10)
    {
        timer.Stop();
        timer.Dispose();
    }
};
timer.Start();

如您所见,它非常难看……而且它假定您实际上不想在 UI 更新之间做任何工作.

As you can see, it's pretty ugly... and it assumes you don't want to actually do any work between UI updates.

另一种替代方法是使用 BackgroundWorker,并使用 ReportProgress 返回 UI 线程添加列表项.

Another alternative would be to simulate your long-running task (sleeping at the moment) on a different thread using BackgroundWorker, and use ReportProgress to come back to the UI thread to add the list item.

这篇关于使用 TaskScheduler.FromCurrentSynchronizationContext 更新 Task 中的 UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆