[英]C#: How to force "calling" a method from the main thread by signaling in some way from another thread
对不起,标题太长,我什至不知道如何表达问题
我正在使用一个库,它从主线程的不同上下文(是一个 C 库)运行回调,我在 C# 中创建了回调,当被调用时,我只想引发一个事件。
但是因为不知道事件里面会发生什么,所以想找到一种方法来调用方法,没有锁等问题(否则第三方用户就得在事件内部处理这个,非常丑陋)
有没有办法做到这一点? 我可能完全走错了路,但我正在考虑用 winforms 的方式来处理不同的线程(.Invoke 的事情)
否则我可以向窗口的消息循环发送消息,但我对消息传递知之甚少,以及我是否可以发送这样的“自定义”消息
例子:
private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
OnConfigure(EventArgs.Empty);
return 0U;
}
这个回调是从另一个我无法控制的程序调用的,我想在主线程(处理我的 winform 的线程)中运行 OnConfigure 方法,该怎么做? 或者换句话说,我想在不需要考虑锁的情况下运行 OnConfigure
编辑1:
我有这个例外的问题:
CallbackOnCollectedDelegate 检索到的消息:在 GarbageCollector 中收集的委托“G19dotNet!G19dotNet.LgLcd+lgLcdOnSoftButtonsCB::Invoke”上运行的回调。 在非托管代码委托期间应确保永远不会被删除,直到您确定它们永远不会被调用
编辑2:
问题由我自己解决,感谢 Stackoverflow 总是帮助我! 供将来参考: 将委托定义为函数指针
如果您正在使用WinForms并且想要在UI线程上执行某些操作,则需要在该线程上创建的某些控件(无论是Button
还是Form
或其他)上Invoke
或BeginInvoke
。 为了做到这一点,你需要一个引用它。
例如,使用您的代码并假设您有一个名为form
的表单的引用:
private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
form.Invoke(new MethodInvoker(() => OnConfigure(EventArgs.Empty)));
return 0U;
}
在调用第三方函数之前,请获取对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.
}));
}
}
这种称为基于事件的异步模式有一种模式 。 链接的文章是关于如何使用它的一个很好的概述。 AsyncOperation类是此模式的关键。
这种模式可能不完全适合您尝试解决的问题,但它可能会让您对问题有所了解。
感谢 Adam Robinson 的回答,我在表单上添加了一个不错的小实用函数:
private void runOnUIThread(Action function)
{
this.Invoke(new MethodInvoker(function));
}
我是这样使用它的:
runOnUIThread(() =>
{
example_lbl_status.Text = "Active";
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.