简体   繁体   中英

Catching an exception thrown in a Thread

I need to know if an exception that happens inside a method called by a Thread can be catch in the main application. I'm doing a Windows forms application and one of the things I have to do is store some data in a database, but I need to inform the user if, for some reason, the operation was unsuccessful (eg if the application couldn't connect to the database). The thing is that I have to call the method to insert the values in the DB from a new Thread, and, therefore, I use the try;catch blocks from inside that method. But if an error occur and the exception is thrown there is nobody able to catch it so the program crashes. I have been doing some google search but all that I could find recommended to use the class Task instead of Thread, but, because this is an assignment from my university, I need to use Threads.

So, is there a way to "transfer" the exception from a Thread to the main thread of the application ? Here's my code so far:

    //This is how I create the new Thread
    public static Correo operator +(Correo c, Paquete p)
    {
        foreach (Paquete paq in c.Paquetes)
        {
            if (paq == p)
                throw new TrackingIDRepetidoException("El paquete ya se encuentra cargado en la base de datos");
        }
        c.Paquetes.Add(p);
        Thread hilo = new Thread(p.MockCicloDeVida);
        hilo.Start();
        c.mockPaquetes.Add(hilo);
        return c; 
    }


    public void MockCicloDeVida()
    {
        while (this.Estado != EEstado.Entregado)
        {
            Thread.Sleep(10000);
            this.Estado += 1;
            this.InformaEstado(this, new EventArgs());
        }
        try
        {
            // A simple method to insert an object in a DB. The try catch to check if the connection to the DB was succesfull or not is implemented here.
            PaqueteDAO.Insertar(this);
        }
        catch (System.Data.SqlClient.SqlException e)
        {
            // I can't catch the exception here
        }
    }

Any help or tips is greatly appreciated. Thanks!

I would use this very useful class: TaskCompletionSource

var tcs = new TaskCompletionSource<object>();
var th = new Thread(() => MockCicloDeVida(tcs));
th.Start();
try
{
    var returnedObj = tcs.Task.Result;
}
catch(AggregateException aex)
{
    Console.WriteLine(aex.InnerExceptions.First().Message);
}

public void MockCicloDeVida(TaskCompletionSource<object> tcs )
{
    Thread.Sleep(10000);
    tcs.TrySetException(new Exception("something bad happened"));
    //tcs.TrySetResult(new SomeObject());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM