BeginInvoke为什么第一次调用先完成?

时间:2012-10-15 16:59:58

标签: asynchronous delegates

我正在测试委托,我已停止在BeginInvoke和EndInvoke上。我想知道这个同伴代码会发生什么。

我认为第一次开始调用将在第二次开始后终止,因为第二次开始调用只有2秒而第一次是3秒。这不就像它的同步调用吗?为什么?

似乎只在使用EndInvoke时调用实际调用。

/// <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;
    }

}

此输出:

一个est终点! Bestendée!

不应该吗?

Bestendée! 一个好的终点!

1 个答案:

答案 0 :(得分:1)

您明确地致电EndInvoke

strReturnedData = dlgt.EndInvoke(arA);

这将等待直到委托完成。鉴于您正在传递arA,它只能 等待第一个委托调用完成。它不可能对第二个委托调用做任何事情,因为你明确地说你想要第一个委托的结果。

  

似乎只在使用EndInvoke时调用实际调用。

不,只是当你阻止代表完成之前就是这样。

如果您在return message;之前添加此代码:

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

然后你会看到输出:

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