捕获线程中引发的异常

时间:2018-06-20 21:46:44

标签: c# multithreading thread-safety

我需要知道在Thread调用的方法内部发生的异常是否可以在主应用程序中捕获。 我正在做Windows窗体应用程序,我要做的一件事情是在数据库中存储一些数据,但是如果由于某种原因操作不成功(例如,如果应用程序无法完成操作),我需要通知用户连接到数据库)。问题是我必须调用该方法以将值从新线程插入数据库中,因此,我从该方法内部使用try; catch块。但是,如果发生错误并且引发了异常,则没有人能够捕获该异常,因此程序将崩溃。 我一直在做一些Google搜索,但是所有可以找到的建议都是使用Task类而不是Thread,但是由于这是我大学的作业,因此我需要使用Threads。

那么,有没有办法将异常从线程“转移”到应用程序的主线程?到目前为止,这是我的代码:

    //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
        }
    }

任何帮助或提示都将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

我将使用这个非常有用的类: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());
}