tags:

views:

189

answers:

2

1) I heard that when we won't call EndInvoke() it may lead to memory leak? can you demonstrate it how could this lead to memory leak?

2) When i suppose to call EndInvoke() shall i use the code like following ?

namespace BlockMechanism
{
    public delegate int MyDelegate(List<int> someInts);
    class MainClass
    {
        static void Main()
        {
           List<int> someInts = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
           MyDelegate test = FinalResult;
           IAsyncResult res=test.BeginInvoke(someInts, null, test);
           Console.WriteLine(test.EndInvoke(res));
           Console.ReadKey(true);
        }

        public static int FinalResult(List<int> Mylist)
        {
            return Mylist.Sum();
        }

    }
}
+3  A: 

While your example is correct there is no benefit from using a different thread because you call EndInvoke on the main thread which will block until the operation completes and it cannot do other work. It would have been equivalent if you called Invoke on the delegate or directly the FinalResult method itself. Usually EndInvoke is called in the callback provided by the BeginInvoke method:

class Program
{
    public delegate int MyDelegate(List<int> someInts);
    class MainClass
    {
        static void Main()
        {
            List<int> someInts = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
            MyDelegate test = FinalResult;
            test.BeginInvoke(someInts, ar => 
            {
                MyDelegate del = (MyDelegate)ar.AsyncState;
                Console.WriteLine(del.EndInvoke(ar));
            }, test);
            Console.ReadKey(true);
        }

        public static int FinalResult(List<int> Mylist)
        {
            return Mylist.Sum();
        }
    }
}

As far as the memory leak is concerned you may take a look at this thread.

P.S: Instance members of the List<T> class are not thread safe so you should be careful when you access them from multiple threads.

Darin Dimitrov
+2  A: 

MSDN article on Begin/EndInvoke()

Basically, if you don't call EndInvoke() you run the risk of leaking something. Generally either memory, or a forever stalled thread in a pool somewhere.

The article discusses four common ways of using BeginInvoke() and when you should call EndInvoke() for each.

For posterity, I'll reproduce them here:

  • Do some work and then call EndInvoke to block until the call completes.

  • Obtain a WaitHandle using the System.IAsyncResult.AsyncWaitHandle property, use its WaitOne method to block execution until the WaitHandle is signaled, and then call EndInvoke.

  • Poll the IAsyncResult returned by BeginInvoke to determine when the asynchronous call has completed, and then call EndInvoke.

  • Pass a delegate for a callback method to BeginInvoke. The method is executed on a ThreadPool thread when the asynchronous call completes. The callback method calls EndInvoke.

Kevin Montrose