Logo
PRB: Visual Studio .NET events being disconnected from add-in.

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: August 2005   Microsoft Visual Studio .NET 2003
Updated: March 2013   Microsoft Visual Studio 2005
      Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012
Introduction

This article describes why after some time a Visual Studio .NET add-in no longer receives events.

More Information

When using a C# add-in to receive events from Visual Studio .NET, it can happen that after a while the add-in no longer receives them. Consider this code:

private _DTE applicationObject;
 
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, 
   object addInInst, ref System.Array custom)
{
   EnvDTE.SolutionEvents solutionEvents;
   
   applicationObject = (_DTE) application;
   solutionEvents = applicationObject.Events.SolutionEvents;
   solutionEvents.Opened += new _dispSolutionEvents_OpenedEventHandler(SolutionOpened);
}
 
private void SolutionOpened()
{
   MessageBox.Show("Solution opened");
}
When you call Events.SolutionEvents, a .NET wrapper object is created around the underlying COM object that Visual Studio (which is a COM application, not a .NET application) holds to raise the events. However, Visual Studio doesn't hold a reference to this .NET wrapper, which is only referenced by the solutionEvents variable. Since this variable is local to the OnConnection procedure, when the procedure exits the variable is no longer used and it will be garbage collected the next time that the garbage collector performs its job. Until that moment you receive events, but after that the event handler is disconnected. To solve this problem, you must declare the solutionEvents variable at class level, not at procedure level:
private _DTE applicationObject;
private EnvDTE.SolutionEvents solutionEvents;
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, 
   object addInInst, ref System.Array custom)
{
   applicationObject = (_DTE) application;
   solutionEvents = applicationObject.Events.SolutionEvents;
   solutionEvents.Opened += new _dispSolutionEvents_OpenedEventHandler(SolutionOpened);
}
 
private void SolutionOpened()
{
   MessageBox.Show("Solution opened");
}

Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this


Top