tags:

views:

1094

answers:

3

One of the frequent causes of memory leaks in .Net are event handlers which are never removed from their source objects.

Will this WCF code cause a memory leak, or will the lamda go out of scope too, allowing both the proxy class and the handler to be GCed?

void AMethod()
{
    WCFClient proxy;
    proxy = new WCFClient();
    proxy.RemoteOperationCompleted += (sender, e) => proxy.Close();
    proxy.Open();
    proxy.RemoteOperationAsync();
}
A: 

That object will die... it'll be cleaned up.

Don't forget that the lamda isn't doing anything special... it's a compiler trick (so just assume it's a normal += SomeDelegate).

Also, the "Close" method (I don't know why they didn't make it IDisposable) will clean up everything else that was left open.

Timothy Khouri
A: 

Don't forget that the proxy's don't correctly implement IDisposable. If an error occurs the code above will not clean up the connection and the handle will remain until the parent process is closed.

Brian Adams
+2  A: 

Here's my test - note the explicit proxy set to null in the lambda - without it the WeakReference lives and therefore a leak is likely:

public class Proxy
{
    private bool _isOpen;

    public event EventHandler Complete;

    public void Close() 
    {
     _isOpen = false;
    }

    public void Open() 
    { 
     _isOpen = true; 
    }

    public void RemoteOperationAsync()
    {
     if (!_isOpen)
      throw new ApplicationException();
     Thread.Sleep(1000);
     if (Complete != null)
      Complete(this, EventArgs.Empty);
    }
}

public static class Program
{
    public static void Main()
    {
     WeakReference wr = null;

     {
      var proxy = new Proxy();
      proxy.Complete += (sender, e) =>
       {
        proxy.Close();
        wr = new WeakReference(proxy);
        proxy = null;
       };
      proxy.Open();
      proxy.RemoteOperationAsync();
     }

     GC.Collect(GC.GetGeneration(wr));
     GC.WaitForPendingFinalizers();

     Console.WriteLine("[LAMBDA] Is WeakReference alive? " + wr.IsAlive);
    }
}
cfeduke