【问题标题】:callbacks in c#, calling order and returnc#中的回调,调用顺序和返回
【发布时间】:2011-05-12 13:46:53
【问题描述】:

关于回调的一个简单问题。回调函数完成后是否返回到调用函数的下一行?

class A
{
 public delegate void A();
 public event A onA;

 public void func()
 {
   //some code 1
  onA();
  //some code 2 
 }

所以问题是 onA 事件会去执行相应的处理程序,然后返回到“一些代码 2”位,还是这是异步的,代码不会等待事件被完全处理?

我希望问题很清楚。

谢谢 }

【问题讨论】:

    标签: c# callback


    【解决方案1】:

    您使用委托的方式:是同步的。如果你想要异步,你必须调用委托:BeginInvoke 方法。

    【讨论】:

      【解决方案2】:

      是的,在您的示例中,onA() 将触发连接到 A 的所有事件处理程序以触发。它们只是将被调用的方法。在它们都被调用之后,控制将返回到 func()。

      它不是异步的——你只使用一个线程。一切都将按照明确定义的顺序发生。

      一个很好的试验方法是使用内置调试器逐步执行示例中的代码。

      【讨论】:

      • 非常感谢。这就是我所期待的。将按照您的建议使用调试器对其进行测试。
      【解决方案3】:

      您的代码不是异步的。但是你可以Use Delegates Asynchronously

      【讨论】:

        【解决方案4】:

        不,调用事件不是异步的事情。您的代码 func() 只会在 onA() 结束运行后继续运行。

        如果你想运行异步代码,你可以使用BeginInvokeThreading

        详细了解委托调用here

        【讨论】:

          【解决方案5】:

          正如其他人所指出的,这完全是同步的。如果您想异步执行此操作,则必须以不同的方式编写。

          此外,如果未订阅事件“onA”,onA() 将引发空引用异常。

          通常的模式是定义一个事件 'Foo' 和一个在事件发生时调用的方法 'OnFoo'。从事件的名称来看,我怀疑这是您想要的 - 例如:-

          class Foo // Class and member names must be distinct
          {
              public delegate void ADelegate();
              public event ADelegate A;
          
              private void OnA()
              {
                  if(A != null)
                      A();
              }
          
              public void Func()
              {
                  // Some code...
                  OnA();
                  // More code...
              }
          }
          

          如果你想异步调用订阅的事件处理程序,你可以使用 BeginInvoke() 和 EndInvoke() 这样:-

          class Foo // Class and member names must be distinct
          {
              public delegate void ADelegate();
              public event ADelegate A;
          
              private void OnA()
              {
                  if (A == null) return;
          
                  // There may be multiple subscribers, invoke each separately.
                  foreach(ADelegate del in A.GetInvocationList())
                      del.BeginInvoke(SubscriberCallback, del);
              }
          
              private void SubscriberCallback(IAsyncResult result)
              {
                  var del = (ADelegate) result.AsyncState;
                  del.EndInvoke(result);
                  // Do something in the callback...
              }
          
              public void Func()
              {
                  // Some code...
                  OnA();
                  // More code...
              }
          }
          

          请注意,此代码不会等待完成事件订阅者的执行,您必须通过事件调用线程化异步结果以确保发生这种情况。

          请注意,“回调”是您在异步 BeginInvoke 中指定的方法(因为它在异步工作完成后被“回调”),并且不会返回到 Func(),因为它是在单独的线程。

          【讨论】:

          • 这里还有其他问题,与线程一样,您可能希望在此处进行一些锁定以避免回调跳入和 EndInvoke()-ing 在 Func() 执行之前(这个导致异常)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-09
          • 2013-11-24
          相关资源
          最近更新 更多