C# “如何确保例外情况”;调用线程无法访问此对象,因为其他线程拥有它";?
在C#WPF应用程序中,如果在以下按钮中单击事件habdler:C# “如何确保例外情况”;调用线程无法访问此对象,因为其他线程拥有它";?,c#,wpf,multithreading,debugging,task-parallel-library,C#,Wpf,Multithreading,Debugging,Task Parallel Library,在C#WPF应用程序中,如果在以下按钮中单击事件habdler: 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
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);
}
);
}
}
应用程序中断,但出现以下异常:
“调用线程无法访问此对象,因为另一个
线程拥有它”
为什么在第一种情况下使用Task.Factory.StartNew()
时不抛出它?有什么办法可以确保这个例外 任务中抛出的异常始终由任务对象本身处理。稍后当您(例如)访问Task.Result属性时,会重新调用异常。这样,异常的处理就留给创建任务的线程了。如果运行第一个代码段并查看输出窗格,您将看到有多个first chance InvalidOperationException记录在那里。异常将被抛出-任务只是将它们隐藏起来,以便稍后重新刷新
Parallel.For
实际上也是这样做的-它隐藏委托中发生的所有异常,然后在循环完成时,它重新引用单个aggregateeexception
中发生的所有异常。您会注意到调试器在调用Parallel.For
的线程中中断,而不是在传递给它的委托中中断
要使任务中的异常传播到调用线程,例如
Parallel。对于
does,请调用任务上的Wait/WaitAll
。是否使用StartNew获得不同的线程ID,并且行线仍然被注释?您的措辞非常不清楚。在任何一种情况下,您都不希望从另一个线程更新UI控件,无论是从StartNew、Parallel.For还是手动开始。请尝试在任务中的代码周围放置Try..catch,并在catch上放置断点。。。你会得到答案的。在这两种情况下,行为完全相同。这会起作用,但在UI线程上调用Wait()
不是一个好主意,因为它会阻止UI。@svick:Parallel。OP中的For
也会阻止UI线程,直到所有子范围都完成
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;
} );
}