c# - Application.ThreadException event for ALL GUI threads -
i have winforms application creates multiple forms, each in own gui thread, (not main gui thread). handle unhandled exception event (application.threadexception) these forms handle errors. handle exceptions worker threads - bit seems working correctly, i'm having trouble exceptions gui threads still:
program.cs:
[stathread] static void main() { attachexceptionhandlers(); application.enablevisualstyles(); application.setcompatibletextrenderingdefault(false); application.run(new form1()); } public static void attachexceptionhandlers() { application.threadexception += new system.threading.threadexceptioneventhandler(application_threadexception); application.setunhandledexceptionmode(unhandledexceptionmode.catchexception); appdomain.currentdomain.unhandledexception += new unhandledexceptioneventhandler(currentdomain_unhandledexception); dispatcher.currentdispatcher.unhandledexception += new system.windows.threading.dispatcherunhandledexceptioneventhandler(currentdispatcher_unhandledexception); }
form1.cs:
//gui thread crash private void button1_click(object sender, eventargs e) { object = null; a.tostring(); } //worker thread crash private void button2_click(object sender, eventargs e) { thread mythread = new thread(() => { object = null; a.tostring(); }); mythread.start(); mythread.join(); } //new thread, new gui crash private void button3_click(object sender, eventargs e) { thread mythread = new thread(() => { using (crashingform form = new crashingform()) //crashing form crashes in it's formload event. { application.run(form); } }); mythread.start(); mythread.join(); }
this code call exception handler in first 2 instances (gui thread crash , worker thread crash) not handle third instance new gui thread created. have found if call program.attachexceptionhandlers(); before application.run(form) line, ok, undesirable have implement logic make sure call program.attachexceptionhandlers() made before call form created on each thread (the call application.setunhandledexceptionmode fails if called after creating form on thread).
this example part of bigger bit of code ideally give user of code simple api call @ start of application (like in program.cs) attach exception handlers. exception handler magic record details exception being thrown before application dies. telling user have track down each time create new gui thread (worker threads don't seem effected issue) , reattach application.threadexception handler not such clean solution.
is there way achieve this, without having re registerer application.threadexception event each time new gui thread created?
is there way achieve this, without having re registerer application.threadexception event each time new gui thread created?
i'm not aware of any, , teammate , have spent amount of time looking it. .net winforms doesn't appear opinionated when comes how create / manage / destroy multiple message pumps.
we use framework methods similar 1 below, in addition retlang's winformsfiber.
using system; using system.threading; using system.windows.forms; internal static class program { [stathread] private static void main() { createformandstartmessagepump(() => createform("first"), onexception, onexception, false, "pumpthread1"); createformandstartmessagepump(() => createform("second"), onexception, onexception, false, "pumpthread2"); // note app shutdown not handled here } private static t createformandstartmessagepump<t>( func<t> createform, threadexceptioneventhandler onthreadexception, unhandledexceptioneventhandler ondomainexception, bool isbackground, string name) t : form { var latch = new manualresetevent(false); t form = null; var thread = new thread(ts => { application.setunhandledexceptionmode(unhandledexceptionmode.catchexception); application.threadexception += onthreadexception; appdomain.currentdomain.unhandledexception += ondomainexception; form = createform(); latch.set(); application.run(); }) { isbackground = isbackground, name = name }; thread.setapartmentstate(apartmentstate.sta); thread.start(); latch.waitone(); return form; } private static form createform(string name) { var form = new form(); form.text = name; form.show(); return form; } private static void onexception(object sender, unhandledexceptioneventargs e) { // ... } private static void onexception(object sender, threadexceptioneventargs e) { // ... } }
Comments
Post a Comment