多线程未处理的异常

时间:2011-03-29 19:47:08

标签: c# .net multithreading

我正在开展一个将启动多个独立流程的项目。我希望他们被孤立到如果一个人意外失败,其他人将继续而不受影响。我已尝试使用POC(下面粘贴)使用AppDomains对其进行测试,但它仍然会崩溃整个父应用程序。

我采取了错误的做法吗?如果是这样,我该怎么办?如果没有,我做错了什么?

class Program
{
    static void Main(string[] args)
    {
        Random rand = new Random();
        Thread[] threads = new Thread[15];
        for (int i = 0; i < 15; i++)
        {
            AppDomain domain = AppDomain.CreateDomain("Test" + i);
            domain.UnhandledException += new UnhandledExceptionEventHandler(domain_UnhandledException);
            domain.
            Test test = domain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, "ConsoleApplication1.Test") as Test;
            Thread thread = new Thread(new ParameterizedThreadStart(test.DoSomeStuff));
            thread.Start(rand.Next());
            Console.WriteLine(String.Format("Thread #{0} has started", i));
            threads[i] = thread;
        }

        for (int i = 0; i < 15; i++)
        {
            threads[i].Join();
            Console.WriteLine(String.Format("Thread #{0} has finished", i));
        }
        Console.ReadLine();
    }

    static void domain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Console.WriteLine("UNHANDLED");
    }


}

public class Test : MarshalByRefObject
{
    public void DoSomeStuff(object state)
    {
        int loops = (int)state;
        for (int i = 0; i < loops; i++)
        {
            if (i % 300 == 0)
            {
                // WILL break
                Console.WriteLine("Breaking");
                int val = i / (i % 300);
            }
        }
    }
}

修改

请注意,“测试”类非常简化。实际的实施非常复杂,并且在异常处理方面存在很大差距。

2 个答案:

答案 0 :(得分:4)

您不需要单独的AppDomains。您需要做的就是捕获Test类的DoSomeStuff成员中的异常。因此,如果其中一个线程处理自己的异常,则应用程序的其余部分可以继续运行。

答案 1 :(得分:0)

你必须在引发它的线程中捕获异常,没有办法解决这个问题。您接下来需要做的是将异常序列化回主应用程序域,以便它知道它。毕竟,它引发了线程以完成某种工作并且该工作尚未完成。应该做些什么。

您要模拟的是SQL Server和ASP.NET的工作方式。他们有一个非常好的执行模型。他们接受从客户端计算机执行工作的请求。如果那个请求遭到轰炸,他们就可以回复一个“对不起,它没有用”的消息。并且像它从未发生过那样耸耸肩,所以appdomains得到很好的支持。

将其留给客户机来处理。很少需要人类的帮助。容易腻,但这并非意外,他们是这样设计的。真正模仿这种执行模式还需要找到其他人来应对这种痛苦。那很难。