【问题标题】:Multithreading Unhandled Exceptions多线程未处理的异常
【发布时间】:2011-03-29 19:47:08
【问题描述】:

我正在开展一个将启动多个独立流程的项目。我希望它们被隔离到一个点,即如果一个意外失败,其他人将继续运行而不会受到影响。我尝试了一个 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);
            }
        }
    }
}

编辑

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

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

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

    【讨论】:

    • 请看我的编辑。在这种情况下,Test 类被过度简化了。异常处理很可能存在差距,这反过来又会导致我试图解决的情况。
    • 我会为 not 在错误/异常处理方面存在差距而努力,这将是一个强大的应用程序,尽管听起来它会给你一些成本。此外,更严格的错误/异常处理将帮助您控制资源使用。你不希望线程经常死掉,你会得到各种各样的资源泄漏,然后进程本身就会变得不稳定。
    【解决方案2】:

    您必须在引发它的线程中捕获异常,这是没有办法的。您接下来需要做的可能是将异常序列化回主应用程序域,以便它知道它。毕竟,它启动了线程来完成某种工作,而该工作没有完成。应该为此做点什么。

    您正在模拟的是 SQL Server 和 ASP.NET 的工作方式。他们有一个非常好的执行模型。他们接受来自客户端机器的执行工作的请求。如果该请求被炸毁,他们可以奢侈地发回“抱歉,它不起作用”的消息。并且耸耸肩,就像它从未发生过一样,得到了 appdomains 的良好支持。

    让客户端机器来处理它。顺便说一句,经常需要人类的帮助。很容易,但它们的设计方式并非偶然。真正模仿这种执行模式还需要找到其他人来处理痛苦。这很难。

    【讨论】:

      猜你喜欢
      • 2014-03-23
      • 1970-01-01
      • 2014-09-10
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      • 2016-02-25
      • 2015-12-30
      相关资源
      最近更新 更多