Jai
Jai

Reputation: 8363

Unable to catch an Exception from Task.Run

I am following this MSDN guide to handle the exceptions within a Task.

This is what I wrote:

var myTask = Task.Run(() =>
    {
        throw new Exception("test");
    });
try
{
    myTask.Wait();
}
catch (Exception e)
{
    return false;
}

I have set a breakpoint within the catch block, but at debug runtime, the code does not reach the breakpoint, and it's giving me:

Exception is unhandled by user code

I have no idea what is going on as I have followed very closely to the example from the MSDN guide. In fact, I copied the example to my project and it's still giving the same problem.

Is there any method I can handle the exception outside the Task? I need to return a boolean value based on the fact if the task throws any Exception or not.

Edit

To make it clearer for some of you, this is a more complete set of codes:

public bool ConnectToService()
{
    try
    {
        // Codes for ServiceHost etc etc, which I'm skipping
        // These codes are already commented out for this test, so they do nothing

        var myTask = Task.Run(() =>
            {
                // Supposed to connect to a WCF service, but just throwing a test exception now to simulate what happens when the service is not running
                throw new Exception("test");
            });
        try
        {
            myTask.Wait();
        }
        catch (Exception e)
        {
            return false;
        }

        return true;
    }

    catch (Exception)
    {
        return false;
    }
}

Caller:

public void DoSomething()
{
    try
    {
        // Other irrelevant stuff
        if (ConnectToService())
        {
            DoAnotherThing();
        }
    }
    catch (Exception)
    {
    }

}

I would also want to point out I have a solution for this, but it's puzzling why an example from MSDN isn't working for me. I would think that my own solution is not elegant, so I'm still looking for a more elegant solution.

Exception taskException = null;
var myTask = Task.Run(() =>
    {
        try
        {
            throw new Exception("test");
        }
        catch (Exception e)
        {
            taskException = e;
        }
    });
try
{
    myTask.Wait();
    if (taskException != null) throw taskException;
}
catch (Exception e)
{
    return false;
}

Upvotes: 8

Views: 10957

Answers (5)

Damon Abdiel
Damon Abdiel

Reputation: 3453

I had the same Problem and solved with ContinueWith

See:

var task = Task.Run(() =>
                {
                    ChatHubWrapper chatHub = Ordem_ServicoBLL.sendMensagemIniciarChatPelaVr(pessoaWrapper.OrdemServico);

                    foreach (var mensagem in chatHub.MensagensEnviadas)
                        ChatHub.sendMensagemTodaSala(pessoaWrapper.OrdemServico.ID, mensagem);
                })
                .ContinueWith((t) =>
                {
                    if (t.IsFaulted)
                        setPanelErrorWhats(t.Exception.InnerException.Message); // or throw new Exception...
                });

                task.Wait();

                if (task.IsCompleted)
                    Response.Redirect(pessoaWrapper.OrdemServico.getUrlViewOSSuporte());

With this you Don't need a create Exception taskException = null;

And is not good to use catch Inside Task.Run

Upvotes: -1

ad1Dima
ad1Dima

Reputation: 3195

According to MSDN Task.Run:

Queues the specified work to run on the thread pool and returns a Task object that represents that work.

So You throwing your exception on different thread than you trying to catch it. You should deal with exception on same thread.

Alternatively you can deal with unhandled exceptions in global AppDomain.UnhandledException event.

Upvotes: 1

Marek Koziorowski
Marek Koziorowski

Reputation: 277

@Jai, please try to move a Task.Run to the inside of try/catch block. I think Task.Run executes imediatelly so you may get exception because of that.

Upvotes: -2

Rohit Garg
Rohit Garg

Reputation: 493

Jai, as mentioned, this code will always work. I think you will have to enable some settings in visual studio. The setting is turned off and because of this, you are getting "Exception not handled by user code".

try checking Under Tools, Options, Debugging, General, Enable just my code.

Also, you can use something like below if you don't like to bother about try/catch stuff :

myTask.ContinueWith(<you can access Exception property here to see if there was an exception>)

Upvotes: 0

Maxim
Maxim

Reputation: 88

When a task is run, any exceptions that it throws are retained and re-thrown when something waits for the task's result or for the task to complete

task.Wait()  Rethrows any exceptions

task.Result  Rethrows any exceptions

As well, your code works correctly

Just press f5 while catching an exception and you will see that will get your point

Upvotes: 4

Related Questions