对不起,对于长标题,我甚至不知道如何表达问题的方式
我正在使用一个库,它从主线程的不同上下文运行回调(是一个C库),我在C#中创建了回调,当我被调用时,我想只提出一个事件。
但是因为我不知道事件内部会是什么,所以我想找到一种方法来调用方法而不会出现锁等问题(否则第三方用户将不得不在事件中处理这个问题) ,非常难看)
有没有办法做到这一点? 我可以完全走错路,但我正在考虑winforms处理不同线程的方式(.Invoke事物)
否则我可以向窗口的消息循环发送消息,但我不太了解消息传递,如果我可以发送这样的“自定义”消息
示例:
private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
OnConfigure(EventArgs.Empty);
return 0U;
}
这个回调是从另一个我无法控制的程序调用的,我想在主线程中运行OnConfigure方法(处理我的winform的那个),怎么做呢? 或者换句话说,我想运行OnConfigure而不需要考虑锁
修改1:
我遇到此异常的问题:
CallbackOnCollectedDelegate已重试 消息:在GarbageCollector中收集的委托'G19dotNet!G19dotNet.LgLcd + lgLcdOnSoftButtonsCB :: Invoke'上运行回调。在非托管代码期间,应确保代理永远不会被删除,直到您确定它们永远不会被调用
编辑2:
我自己解决了问题,感谢Stackoverflow总能帮助我! 供将来参考:Defining a delegate as a function pointer
答案 0 :(得分:6)
如果你正在使用WinForms而你想在UI线程上执行某些操作,则需要在某个控件上调用Invoke
或BeginInvoke
(无论是Button
还是在该线程上创建的Form
或其他)。为了做到这一点,你需要引用它。
例如,使用您的代码并假设您有一个名为form
的表单的引用:
private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
form.Invoke(new MethodInvoker(() => OnConfigure(EventArgs.Empty)));
return 0U;
}
答案 1 :(得分:3)
在调用第三方函数之前,请获取对Dispatcher.CurrentDispatcher的引用。在回调函数中,使用dispatcher.Invoke。
你最终得到的结果将是这样的:
class MyClass
{
private Dispatcher dispatcher;
public void runThirdParty()
{
this.dispatcher = Dispatcher.CurrentDispatcher;
callThirdPartyFunction(myCallBack);
}
public void myCallBack()
{
this.dispatcher.Invoke(new Action(() =>
{
//code to run here.
}));
}
}
答案 2 :(得分:3)
这种模式称为Event-based Asynchronous Pattern。链接的文章是关于如何使用它的一个很好的概述。 AsyncOperation类是此模式的关键。
此模式可能与您尝试解决的问题不完全吻合,但它可能会为您提供一些问题的见解。