我现在有一个运行多个任务的小型控制台应用程序(使用Parallel.ForEach)和这些任务的每一个创建使用线程池子线程.QueueUserWorkItem。如何捕捉控制台应用程序从工作线程错误使用C#编写
我想应用程序来处理这些任务/线程抛出的任何异常。
将围绕Parallel.ForEach语句在try..catch工作,如果线程抛出任何错误或他们只会死了呢?
编辑:这些子线程模拟系统的用户。请参阅this question.
我现在有一个运行多个任务的小型控制台应用程序(使用Parallel.ForEach)和这些任务的每一个创建使用线程池子线程.QueueUserWorkItem。如何捕捉控制台应用程序从工作线程错误使用C#编写
我想应用程序来处理这些任务/线程抛出的任何异常。
将围绕Parallel.ForEach语句在try..catch工作,如果线程抛出任何错误或他们只会死了呢?
编辑:这些子线程模拟系统的用户。请参阅this question.
周边的语句不会做的工作。你可以这样做:
public static void Main(string[] args)
{
string[] files = System.IO.Directory.GetFiles(@".", "*.*");
Parallel.ForEach(files, x =>
{
try
{
MyAction(x);
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
}
static void MyAction(string x)
{
throw new ApplicationException("Testing: " + x);
}
会与周围的工作在try..catch的Parallel.ForEach声明如果线程抛出任何错误或他们只会死了呢?
不,你需要把try/catch放在子线程内。
错误处理必须在任务本身(每个作业)来实现。您需要确保您正在创建的任务处理异常。
Parallel.ForEach
将不会为您处理它,因为在调用Parallel.ForEach
的线程中不会引发异常。
选择是使用Task<T>
。
你可以处理的try/catch所有的异常,例如:
try
{
MyParallelMethod();
}
catch(Exception e)
{
//...
}
,并在你的方法,做这样的事情:
public void MyParallelMethod()
{
var data = new List<String>();
//...
Parallel.ForEach(data, d =>
{
try
{
//...
}
catch (Exception e)
{
//...
}
});
}
请勿使用QUWI。我有后台任务类型简要对比on my blog(Task
,BackgroundWorker
,Delegate.BeginInvoke
,ThreadPool.QueueUserWorkItem
和Thread
)。
后台任务,Task
是明显的赢家。与之相比,QueueUserWorkItem
非常低级。
特别是,你的问题是错误传播,Task
内置支持这完全缺乏QueueUserWorkItem
。您可以通过包装在try
/catch
您的代理,存储例外作为委托参数的一部分构建它自己(或lambda表达式的约束变量),明确检查它后,并做一些technically unsupported reflection保存堆栈跟踪。
但为什么要麻烦? Task
支持开箱即用的错误传播。
嗨,应该有一些事件处理程序添加Thread.UnhandledException或类似... – 2011-03-16 12:40:36
为什么你要在'Parallel.ForEach'循环中的任务内调用'ThreadPool.QueueUserWorkItem'? – 2011-03-16 12:41:03
如果你围绕Parallel.ForEach它应该抓住的任何循环迭代中引发的任何异常。它会更好把try/catch语句内的for循环您捕捉实际的异常的源泉,而不是当它抛出的并行算法的呀?也可能取决于你试图捕捉什么异常 – timothyclifford 2011-03-16 12:46:38