Can I connect to the AppDomain.UnhandledException event?

I am trying to create an AppDomain and attach it to the UnhandledException event from F #, and I'm out of luck. In my event handler, I need a link to the domain that triggered the event, as well as event arguments.

To reproduce this problem, the following code must be running in a compiled application. Running in F # Interactive results in another, possibly unrelated, error.

open System open System.Reflection let domainError (domain:AppDomain) (args:UnhandledExceptionEventArgs) = () let domain = AppDomain.CreateDomain("test") domain.UnhandledException |> Event.add (domainError domain) 

This compiles just fine, but at runtime I get the following error:

SerializationException: enter " Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers+h@720 " in the assembly "FSharp.Core, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a" is not marked as serializable.

The stack trace that accompanies this error is as follows:

 at System.AppDomain.add_UnhandledException(UnhandledExceptionEventHandler value) at Program.clo@9.Invoke (UnhandledExceptionEventHandler eventDelegate) in c:\users\joel\documents\visual studio 2010\Projects\EventTest\Program.fs:line 9 at Mi crosoft.FSharp.Core.CompilerServices.RuntimeHelpers.CreateEvent@ 716.Subscribe(IObserver`1 observer) at Microsoft.FSharp.Control.CommonExtensions.SubscribeToObservable[T](IObservable`1 x, FSharpFunc`2 callback) at Microsoft.FSharp.Control.EventModule.Add[T,TDel](FSharpFunc`2 callback, IEvent`2 sourceEvent) at <StartupCode$EventTest> .$Program.main@ () in c:\users\joel\documents\visual studio 2010\Projects\EventTest\Program.fs:line 9 

Now, obviously, I cannot make Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers+h@720 serializable, so can anyone suggest an efficient way to bind to this particular event? Thanks for any suggestions.

Update

Thanks to the ChaosPandion suggestion, this version works:

 open System open System.Reflection let domainError (sender:obj) (args:UnhandledExceptionEventArgs) = let problemDomain = sender :?> AppDomain printfn "Unhandled exception in app domain: %s" problemDomain.FriendlyName () let domain = AppDomain.CreateDomain("test") domain.UnhandledException.AddHandler(UnhandledExceptionEventHandler(domainError)) 
+4
source share
1 answer

After a bit more tweaking, I found that this example would fail:

 let domainError (domain:AppDomain) = let handler (sender:obj) (e:UnhandledExceptionEventArgs) = let msg = (e.ExceptionObject :?> Exception).Message printfn "An exception was unhandled in %s\nMessage:%s" domain.FriendlyName msg new UnhandledExceptionEventHandler(handler) let main() = let domain = AppDomain.CreateDomain("test") let handler = domainError domain domain.UnhandledException.AddHandler handler 

I broke Reflector and found the root cause. (In fact, it is now quite obvious what I think about it.)

 internal class handler@28 : OptimizedClosures.FSharpFunc<object, UnhandledExceptionEventArgs, Unit> { // Fields public AppDomain domain; // Methods internal handler@28 (AppDomain domain); public override Unit Invoke(object sender, UnhandledExceptionEventArgs e); } 

This pretty much means that the only way to get this to work is to not create a closure around the domain object. I'm not sure if this will work for you, but you can try using the following from the handler.

 AppDomain.CurrentDomain 
+3
source

All Articles