捕获在不同线程中抛出的异常

Sil*_*ent 106 c# multithreading exception-handling

我的一个方法(Method1)产生一个新线程.该线程执行一个方法(Method2),并在exectution期间抛出异常.我需要获取有关调用方法的异常信息(Method1)

在某种程度上,我可以捕获这个Method1被抛出的异常Method2吗?

oxi*_*min 176

.NET 4及更高版本中,您可以使用Task<T>类而不是创建新线程.然后,您可以使用.Exceptions任务对象上的属性获取异常.有两种方法可以做到:

  1. 在一个单独的方法中://您在某个任务的线程中处理异常

    class Program
    {
        static void Main(string[] args)
        {
            Task<int> task = new Task<int>(Test);
            task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
            task.Start();
            Console.ReadLine();
        }
    
        static int Test()
        {
            throw new Exception();
        }
    
        static void ExceptionHandler(Task<int> task)
        {
            var exception = task.Exception;
            Console.WriteLine(exception);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在同一方法中://您在调用者的线程中处理异常

    class Program
    {
        static void Main(string[] args)
        {
            Task<int> task = new Task<int>(Test);
            task.Start();
    
            try
            {
                task.Wait();
            }
            catch (AggregateException ex)
            {
                Console.WriteLine(ex);    
            }
    
            Console.ReadLine();
        }
    
        static int Test()
        {
            throw new Exception();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

请注意,您获得的例外是AggregateException.所有真正的例外都可通过ex.InnerExceptions财产获得.

.NET 3.5中,您可以使用以下代码:

  1. //您在线程中处理异常

    class Program
    {
        static void Main(string[] args)
        {
            Exception exception = null;
            Thread thread = new Thread(() => SafeExecute(() => Test(0, 0), Handler));
            thread.Start();            
    
            Console.ReadLine();
        }
    
        private static void Handler(Exception exception)
        {        
            Console.WriteLine(exception);
        }
    
        private static void SafeExecute(Action test, Action<Exception> handler)
        {
            try
            {
                test.Invoke();
            }
            catch (Exception ex)
            {
                Handler(ex);
            }
        }
    
        static void Test(int a, int b)
        {
            throw new Exception();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 或者//您在调用者的线程中处理异常

    class Program
    {
        static void Main(string[] args)
        {
            Exception exception = null;
            Thread thread = new Thread(() => SafeExecute(() => Test(0, 0), out exception));
    
            thread.Start();            
    
            thread.Join();
    
            Console.WriteLine(exception);    
    
            Console.ReadLine();
        }
    
        private static void SafeExecute(Action test, out Exception exception)
        {
            exception = null;
    
            try
            {
                test.Invoke();
            }
            catch (Exception ex)
            {
                exception = ex;
            }
        }
    
        static void Test(int a, int b)
        {
            throw new Exception();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • @SilverlightStudent好的,我刚刚更新了我的答案以满足您的要求. (2认同)
  • @SilverlightStudent在这种情况下,我将传递一个lambda而不是`Test`.像`()=> Test(myParameter1,myParameter2)` (2认同)
  • @SilverlightStudent:已更新. (2认同)

erm*_*mau 9

您无法在Method1中捕获异常.但是,您可以捕获Method2中的异常并将其记录到原始执行线程随后可以读取和使用的变量中.