gpt4 book ai didi

c# - 在 UI 上下文中开始的任务

转载 作者:太空宇宙 更新时间:2023-11-03 14:44:08 28 4
gpt4 key购买 nike

我有这段代码可以异步运行“繁重”的任务(并可能在 UI 上显示结果)。以我的理解,一个新的任务总是会在不同于 UI 的上下文中开始。为了对此进行测试,我编写了以下代码:

private async void button2_Click(object sender, EventArgs e)
{
label2.Text = Thread.CurrentContext.ContextID.ToString();
await Task.Run(() =>
{
Thread.Sleep(2000);
label2.Text = Thread.CurrentContext.ContextID.ToString();
Thread.Sleep(2000);
});

label2.Text = Thread.CurrentContext.ContextID.ToString();
}

我认为,任务(在另一个上下文中运行)不能修改 UI 上下文中的值。这是由任务中的 label2.Text = Thread.CurrentContext.ContextID.ToString(); 行完成的。它完美地工作。 Thread.CurrentContext.ContextID 在任务内部和外部也是相同的。我还检查了当前线程(代码中未显示),它在任务内部有所不同。

我认为我对 Tasks 的理解有误。为什么此任务在与 UI 相同的上下文中启动,即使它在不同的线程中运行?

最佳答案

从一些基本测试看来,你没有得到跨线程异常的唯一原因是你从另一个线程放置在 label2 中的文本与已经存在的文本匹配,因此不需要更新,在我的案例 Thread.CurrentContext.ContextID 是 0。

例如:

private async void button2_Click(object sender, EventArgs e)
{
label2.Text = "Null";
await Task.Run(() =>
{
Thread.Sleep(2000);
label2.Text = SynchronizationContext.Current?.ToString() ?? "Null";
Thread.Sleep(2000);
});

label2.Text = "Done";
}

但是,如果我们更改文本,该代码将无一异常(exception)地运行:

private async void button2_Click(object sender, EventArgs e)
{
label2.Text = SynchronizationContext.Current.ToString(); //WinForms Sync Context
await Task.Run(() =>
{
Thread.Sleep(2000);
label2.Text = SynchronizationContext.Current?.ToString() ?? "Null";
Thread.Sleep(2000);
});

label2.Text = "Done";
}

现在我们得到了预期的交叉线程,InvalidOperationException。因此,如果我们不修改 UI 线程组件的值,则不会发生异常,如果我们修改该值,则会得到预期的异常。

关于c# - 在 UI 上下文中开始的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55265409/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com