开发者

Multithreading Unhandled Exceptions

I am working on a project that will kick off multiple independent processes. I would like them to be isolated to the point that if one fails unexpectedly, the others will continue on wit开发者_运维技巧hout being impacted. I have tried a POC (pasted below) to test this using AppDomains but it still crashes the entire parent application.

Am I taking the wrong approach? If so, what should I be doing? If not, what am I doing wrong?

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);
            }
        }
    }
}

EDIT

Please note that the "Test" class is extremely simplified. The actual implimentation would be extremely complex and have a very likely gap in exception handling.


You don't need separate AppDomains. All you need to do is to catch exceptions in the DoSomeStuff member of the Test class. Thus if one of these threads handles its own exception, then rest of your app can continue running.


You have to catch the exception in the thread that raised it, there's no way around that. What you need to do next is probably serialize the exception back to the primary appdomain so it is aware of it. After all, it set off the thread to get some kind of job done and that job wasn't completed. Something ought to be done about that.

What you are emulating is the way that SQL Server and ASP.NET work. They have a very nice execution model. They accept requests to perform work from client machines. If that request bombs, they have the luxury of sending back a "sorry, it didn't work" message back. And shrug it off like it never happened, so nicely supported by appdomains.

Leaving it up to the client machine to deal with that. Not infrequently requiring the assistance of a human btw. Easy peasy, but it wasn't an accident they were designed that way. Truly emulating this execution model also requires finding somebody else to deal with the misery. That's difficult.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜