gpt4 book ai didi

c# - 如何确保异常 "The calling thread cannot access this object because a different thread owns it"?

转载 作者:行者123 更新时间:2023-11-30 22:19:03 25 4
gpt4 key购买 nike

在C# WPF 应用程序中,如果在以下按钮单击事件处理程序中:

private void start_Click(object sender, RoutedEventArgs e)
{
for (int i = 2; i < 20; i++)
{
var t = Task.Factory.StartNew
(() =>
{
var result=Thread.CurrentThread.ManagedThreadId.ToString();
//this.Dispatcher.BeginInvoke(new Action(() =>
textBlock1.Text += "root " + i.ToString() + " " +
result + Environment.NewLine
;//to comment this line if to uncomment th others
//), null);
}
);
}
}

取消注释行,即通过 Dispatcher.BeginInvoke() 输出到文本 block ,然后用不同的线程 ID 填充它。

尽管有注释行,如上所示,文本 block 保持空白并且没有抛出异常。

在类似情况下使用 Parallel.For

private void start_Click(object sender, RoutedEventArgs e)
{
Parallel.For(2, 6, (i)
=> {
var result = Thread.CurrentThread.ManagedThreadId.ToString();
textBlock1.Text += "root " + i.ToString() + " " +
result + Environment.NewLine;

} );
}

应用程序异常中断:

"The calling thread cannot access this object because a different thread owns it"

为什么在使用 Task.Factory.StartNew() 时在第一种情况下不抛出?
有什么办法可以确保这个异常(exception)?

最佳答案

任务中抛出的异常总是由任务对象本身处理。当您访问 Task.Result 属性时,稍后会重新抛出异常。这样,异常的处理就留给了创建任务的线程。如果您运行第一个代码片段并查看“输出” Pane ,您会看到那里记录了多个第一次机会 InvalidOperationException。异常抛出 - 任务只是将它们藏起来以备日后重新抛出。

Parallel.For 实际上做了同样的事情 - 它隐藏了委托(delegate)中发生的所有异常,然后,当循环完成时,它重新抛出在单个 AggregateException< 中发生的所有异常。您会注意到调试器在调用 Parallel.For 的线程中中断,而不是在传递给它的委托(delegate)中中断。

要使任务中的异常传播到调用线程,如 Parallel.For 所做的那样,请在任务上调用 Wait/WaitAll

关于c# - 如何确保异常 "The calling thread cannot access this object because a different thread owns it"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15765147/

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