Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to try..catch ThreadPool.QueueUserWorkItem code

I have bunch of Asynchronous commands. I want to write try..catch without much of repeating. Example:

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

AsynchronousCommand is class that invokes Action using ThreadPool.QueueUserWorkItem( (state) => { action() } );.

Try..catch works well when is inside lambda:

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

When outside then not:

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

Exception is not catched.

Edit

I want to catch Exception not when creating command: when executing it using command.DoExecute(this) and if possible put try..catch inside lambda.

like image 830
Tomasito Avatar asked Jun 12 '26 13:06

Tomasito


2 Answers

Exceptions propagate up the call stack on the thread on which they are thrown. Because the commands run on a thread pool thread, it will be on a different thread to your try ... catch hence it doesn't get caught.

EDIT: Assuming you do actually invoke the command within the try ... catch

like image 78
Chris Ballard Avatar answered Jun 14 '26 02:06

Chris Ballard


You can get these semantics through the use of await. It when you await something it will schedule the remainder of the method as a continuation of the previous method, meaning that the operation is performed asynchronously. However, when the awaited operation finishes, if it represents something that throws an exception, that exception will be caught and then re-thrown within the context of your next continuation, allowing you to wrap a series of asynchronous operations in a single try/catch, having the syntax and semantics you desire. A simple example might look like:

public static async Task Foo()
{
    try
    {
        await Task.Run(() => DoSomething());
        await Task.Run(() => DoSomethingElse());
    }
    catch(Exception e)
    {
        Console.WriteLine(e);
    }
}

Here DoSomething and DoSomethingElse will be run in a thread pool thread, and if either throws an exception when running, not when being started, then the catch block will be hit.

like image 30
Servy Avatar answered Jun 14 '26 04:06

Servy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!