Rushino
Rushino

Reputation: 9495

BeginInvoke Why is the first invoke finished first?

I was testing delegates and ive stopped on BeginInvoke and EndInvoke. I wonder what happen in this fellowing code.

I though that the first begin invoke would terminate after the second since the second is only 2 seconds and the first one is 3 seconds. Don't this make it like its a sync call ? Why ?

It seem the actual call is only called when EndInvoke is used.

/// <summary>
/// Démonstration d'un appel d'une méthode ASYNCRONE avec BeginInvoke() SANS rappel (Callback).
/// </summary>
public class AsyncBeginInvokeDemo
{
    // Voici la méthode délégué.
    // L'équivalent: Func<int, string> (Func<In1, ..., Out>)
    // Note: Aurait pu être également Action<int> si la méthode ne retourne pas de valeurs.
    delegate string MethodDelegate(int iCallTime, string message);

    /// <summary>
    /// Démarrer la démonstration.
    /// </summary>
    public void Start()
    {
        string strReturnedData = String.Empty;

        // Attaché la méthode au délégué.
        MethodDelegate dlgt = new MethodDelegate(this.LongRunningMethod);

        // Initié l'appel asyncrone A.
        IAsyncResult arA = dlgt.BeginInvoke(3000, "A est terminée!", null, null);

        // Initié l'appel asyncrone B.
        IAsyncResult arB = dlgt.BeginInvoke(2000, "B est terminée!", null, null);

        // Retrieve the results of the asynchronous call.
        strReturnedData = dlgt.EndInvoke(arA);
        Console.WriteLine(strReturnedData);
        strReturnedData = dlgt.EndInvoke(arB);
        Console.WriteLine(strReturnedData);
    }

    /// <summary>
    /// Il s'agit de l'opération à executé.
    /// </summary>
    /// <param name="iCallTime">Temps d'execution de l'opération. (Simulation)</param>
    /// <returns>Données par l'opération. (Simulation)</returns>
    public string LongRunningMethod(int iCallTime, string message)
    {
        // Mettre le thread en attente pendant un nombre de milliseconde x.
        Thread.Sleep(iCallTime);

        // Retourner des données.
        return message;
    }

}

This output :

A est terminée! B est terminée!

Shouldn't it be ?

B est terminée! A est terminée!

Upvotes: 0

Views: 93

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500565

You're explicitly calling EndInvoke:

strReturnedData = dlgt.EndInvoke(arA);

That will wait until the delegate has finished. Given that you're passing in arA, it can only wait for the first delegate call to finish. It can't possibly do anything with the second delegate call, because you're explicitly saying that you want the results of the first delegate.

It seem the actual call is only called when EndInvoke is used.

No, it's just that that's when you block until the delegate has completed.

If you add this code just before return message;:

Console.WriteLine("Finished {0}", message);

Then you'll see output of:

Finished B est terminée!
Finished A est terminée!
A est terminée!
B est terminée!

Upvotes: 1

Related Questions