如何尝试..catch ThreadPool.QueueUserWorkItem代码

时间:2014-03-06 15:25:14

标签: c# exception-handling threadpool

我有一堆异步命令。我想写try..catch而不用重复。例如:

_fooCommand = new AsynchronousCommand( () => { action } );
_barCommand = new AsynchronousCommand( () => { action } );

AsynchronousCommand是使用Action调用ThreadPool.QueueUserWorkItem( (state) => { action() } );的类。

在lambda中使用Try..catch效果很好:

_fooCommand = new AsynchronousCommand( () => { try.exception.catch } );

外面不在时:

try
    _fooCommand = new AsynchronousCommand( () => {...} );
catch

没有捕获异常。

修改

我想在创建命令时捕获异常:当使用command.DoExecute(this)执行它时,如果可能的话,将try..catch放在lambda中。

2 个答案:

答案 0 :(得分:3)

异常在调用它们的线程上传播调用堆栈。因为命令在线程池线程上运行,所以它将与您的try ... catch位于不同的线程上,因此它不会被捕获。

编辑:假设您实际上调用 try ... catch

中的命令

答案 1 :(得分:2)

您可以通过await使用这些语义。当你await时,它将调度方法的其余部分作为前一个方法的延续,这意味着操作是异步执行的。但是,当等待的操作完成时,如果它表示抛出异常的内容,那么该异常将被捕获,然后在下一个continuation的上下文中重新抛出,允许您将一系列异步操作包装在一个{{1拥有你想要的语法和语义。一个简单的例子可能如下:

try/catch

此处public static async Task Foo() { try { await Task.Run(() => DoSomething()); await Task.Run(() => DoSomethingElse()); } catch(Exception e) { Console.WriteLine(e); } } DoSomething将在线程池线程中运行,如果在运行时抛出异常,而不是在启动时抛出,那么{{1阻止将被击中。