2010-05-04 132 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

相关问题