2010-05-04 176 views
1

我有一個使用C++ DLL的C#應用​​程序。 C++ DLL非常簡單。我可以調用一個方法,並且它有一個回調方法。回調方法必須先完成,然後才能處理下一個項目。在回調完成後執行方法

問題是,我一次只能處理一個命令,但我想盡可能快地處理它們。

假/簡化代碼,接口爲C++ DLL:

void AddNumbers(int a, int b, AddNumbersCallback callback); 

現在讓我們嘗試使用它:

void DoStuff() 
{ 
    if(MyCollection.HasStuff) 
      AddNumbers(MyCollection.First().a, MyCollection.First.b, StuffDone); 
} 

void StuffDone(int result) 
{ 
    //I wish I could process the next item here, but the callback isn't done! 
    //DoStuff(); 
} 

問題的根源是,我想後執行代碼回調是完成

我的臨時解決方案是在線程池中排隊一個項目,並等待100ms。通常情況下,這會給方法時間「完成」。

而「否」,我無法更改DLL。

+0

將'DoStuff()'作爲'StuffDone'的最後一行而不是「after」調用有什麼不同? – 2010-05-04 12:38:42

+0

如果在回調完成之前再次調用該函數會發生什麼?它似乎違背了「異步」的整個定義,以及C#中的回調函數作爲一個整體的含義,它需要你等待。 – cHao 2010-05-04 12:42:16

+0

在DoStuff和StuffDone都使用Console.WriteLine(Thread.CurrentThread.ManagedId)。如果你得到不同的數字,那麼你有一個問題,你不能可靠地解決。如果你不這麼做,那麼只需在AddNumbers()調用之後運行代碼即可。 – 2010-05-04 13:28:22

回答

2

如果函數是真正的異步函數,那麼不管你調用多少次,或者在多次調用之間等待多久。 (閱讀:你的DLL壞了。)在這種情況下,如果你真的需要同步,你可能會想要在循環中使用EventWaitHandle。

using System.Threading; 

EventWaitHandle done = new EventWaitHandle(false, EventResetMode.AutoReset); 

void DoStuff() 
{ 
    while (MyCollection.HasStuff) 
    { 
     // note: something smelled fishy here. 
     // i assume your collection removes the first entry when you call First 
     var first = MyCollection.First(); 
     AddNumbers(first.a, first.b, StuffDone); 
     done.WaitOne(); 
    } 
} 

void StuffDone(int result) 
{ 
    done.Set(); 
} 
+0

但是,這是否確保「done.WaitOne();」行將不會讓執行繼續,直到「StuffDone」完成? 問題似乎是,在我可以處理下一個項目之前,「StuffDone」必須脫離調用堆棧。 – 2010-05-04 13:08:44

+0

事實上,如果不事先知道兩個線程的線程句柄,你就不能真正保證類似的東西,沒有任何值得它花錢的DLL會依賴於你編碼。我在想這個DLL可能並不是真的異步(它只是在完成時調用回調函數),並且有很多條目,從回調函數調用DoStuff()會溢出堆棧。 EventWaitHandle的東西應該解釋這種情況,以及什麼時候真的是異步的,並且你正在等待你在StuffDone中做的任何處理。 – cHao 2010-05-04 13:31:14

+0

這對我很好。 「WaitOne」非常易於使用。 – AlbatrossCafe 2017-03-31 16:10:32

相關問題