Terry,
I have seen the "The target application domain has been unloaded." error when an add-in hooks up to an event in the host, then the add-in is unloaded, then the event fires in the host.
This happens when add-ins are unloaded like:
internal void
Disconnect()
{
foreach
(IEntryPoint ep in this.addInList)
{
try
{
ep.OnShutdown();
}
catch
(Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception unloading addIn");
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
AddInController controller =
AddInController.GetAddInController(ep);
controller.Shutdown();
}
this.addInList.Clear();
}
When add-ins are unloaded like this, no error is raised (that I've seen so far); however, the unloaded add-in catches the event and executes what ever code the add-in hooked into the event.
internal
void Disconnect()
{
foreach
(IEntryPoint ep in this.addInList)
{
ep.OnShutdown();
}
this.addInList.Clear();
}
We have reported this to Microsoft as a bug and will pass on any feedback we get back.
In the mean time there are two ways to get around this.
One is to ensure that all events hooked into
by an add-in are removed in the OnShutdown method.
The second is to use an EventHelper class
which unhooks any events that cause errors.
Here’s an example of an EventHelper class- it’s based off the
EventHelper class included with the VSTA v 1 SDK samples.
*Notice with Visual Basic you append the event with Event when passing it to the EventHelper.
Public Event
CreatedDrawing As CreatedDrawingEventHandler
Public Function NewDrawing() As
Drawing
Dim
newDrawing_value As Drawing = New Drawing(Me)
EventHelper.Invoke(CreatedDrawingEvent,
Me, New
CreatedDrawingEventArgs(newDrawing_value))
End Function
Imports System
Imports System.Collections.Generic
Imports System.Text
Friend Class
EventHelper
'Invoke all delegates.
If a delegate is a proxy for an add-in,
'catch any exceptions and remove the delegate from the
invocation list.
Public Shared Sub Invoke(ByVal
eventDelegate As MulticastDelegate, ByVal ParamArray
args() As Object)
If Not eventDelegate Is Nothing Then
'get the list of delegates
Dim list As
System.Delegate() = eventDelegate.GetInvocationList()
'create an empty list of delegates to store
delegates to be removed
Dim blockList As
List(Of [Delegate]) = New
List(Of [Delegate])(list.Length)
'FOR each delegate in the list
For Each
handler As [Delegate] In
list
Try
'attempt to invoke it
CType(handler,
MulticastDelegate).DynamicInvoke(args)
Catch ex As
Exception
'IF the invoke failed, add the delegate to the
list of delegates to be removed
blockList.Add(handler)
End Try
Next
'delegate
'FOR each delegate to be removed
For Each
handler As [Delegate] In
blockList
'remove the handler
System.Delegate.Remove(eventDelegate, handler)
Next
'delegate to be removed
End If 'the eventDelegate
has a value
End Sub
End Class
I hope this helps, please let me know if you have any questions.
Thanks!
-Melody