Martin
Martin

Reputation: 189

Why does BackgroundWorker not need to call EndInvoke when it calls BeginInvoke on a delegate?

This post says that when you call the BeginInvoke method on a delegate, it is always necessary to call the EndInvoke method. Another post backs it up and suggests the class BackgroundWorker as an alternative.

I used ILSpy to decompile BackgroundWorker and I have found out that actually, EndInvoke is never called in this class, even though it does use BeginInvoke on a delegate.

Does this mean that BackgroundWorkder is ill-implemented, or is calling EndInvoke not so necessary after all?

(The issue with exceptions being lost is irrelevant, since the whole method being invoked is enclosed in a try-catch block)

On a similar matter: it there a clear reason why BeginInvoke was chosen in implementation of BackgroundWorker over say, ThreadPool.QueueUserWorkItem()?

Edit: the source code of BackgroundWorker can be viewed here.

Upvotes: 3

Views: 165

Answers (1)

Hans Passant
Hans Passant

Reputation: 941505

I looked for the man-behind-the-curtain for a while. The CLR has secret knowledge of the SynchronizationContext class so technically it could be involved here. Found absolutely nothing.

Until I checked what I should have done in the first place, actually verify the claim that EndInvoke() is required:

using System;

class Program {
    static void Main(string[] args) {
        Action d = null;
        d = new Action(() => {
            d.BeginInvoke(null, null);
        });
        d();
        Console.ReadLine();
    }
}

Runs like gangbusters and consumes plenty of handles. But it won't blow up, they never go over ~2000 and memory usage is completely stable.

So perhaps it is appropriate to tweak the claim that calling a delegate's EndInvoke() is required. If you have a priori knowledge that the delegate target will not doing anything unusual, like calling into another AppDomain, running native code or activate remoted code then you can get away with not calling EndInvoke(). A guarantee that BackgroundWorker can provide. I can never make that claim stick as just a mere SO user. But Microsoft does it so it must be okay. A comment in the source code would have been nice.

Upvotes: 1

Related Questions