【问题标题】:BeginInvoke Why is the first invoke finished first?BeginInvoke 为什么第一个调用先完成?
【发布时间】:2012-10-16 01:07:08
【问题描述】:

我正在测试代表,我停止了 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;
    }

}

这个输出:

即将结束! 最好的终结者!

不应该吗?

最好的终结者! 终于结束了!

【问题讨论】:

  • 鉴于 Stack Overflow 是一个英文网站,在发布之前将所有 cmets 转换为英文是值得的......

标签: asynchronous delegates


【解决方案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!

【讨论】:

  • 我就是这样!感谢您的确认!
  • @Rushino:不,您显然认为代理仅在调用 EndInvoke 时才开始,但事实并非如此。查看我的编辑。
  • 你是对的。但是,当我说“我虽然如此”时,这不是我的意思。在你回答之前,我想在这之后。我告诉自己也许 EndInvoke 等待调用完成,这是有道理的,因为你想返回一些东西。这就是为什么我对我的评论感到困惑时说“我认为”的原因。此外,使用回调可能是避免此类错误的好方法。
猜你喜欢
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多