2011-05-12 35 views
5

一個簡單的回調問題。完成後,回調函數是否會返回調用函數中的下一行?c#中的回調,調用訂單並返回

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

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

所以現在的問題是將ONA事件去執行相應的處理程序,然後回來「一些代碼2」位或這是異步代碼不會等待事件被完全處理?

我希望問題很清楚。

感謝 }

回答

2

是的,在你的例子中,onA()會觸發所有事件處理程序連接到A來觸發。他們只是將被調用的方法。他們都被調用後,控制權將返回到func()。

它不是異步的 - 你只使用一個線程。一切都將按照明確的順序進行。

一個很好的實驗方法是使用內置的調試器遍歷示例中的代碼。

+0

非常感謝。這就是我期待的。將按照您的建議使用調試器進行測試。 – user642770 2011-05-12 15:50:24

3

您使用委託的方式:是同步的。如果你想異步,你必須使用:BeginInvoke方法調用委託。

1

不,調用一個事件不是一個assync的東西。您的代碼func()只會在onA()結束運行後繼續。

如果您想要運行assync代碼,您可以使用BeginInvokeThreading

閱讀更多關於委託調用here

0

正如其他人所指出的,這完全是同步的。如果你想異步執行這個,你必須以不同的方式寫這個。此外,如果事件'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(),因爲它在單獨的線程。

+0

這裏還有其他一些問題,像線程一樣,你可能想在這裏做一些鎖定以避免回調跳入和EndInvoke() - 在Func()執行之前(這會導致異常)。 – ljs 2011-05-12 14:38:59