C# C:“如何强制”;呼唤;通过以某种方式从另一个线程发送信号来从主线程发送的方法

C# C:“如何强制”;呼唤;通过以某种方式从另一个线程发送信号来从主线程发送的方法,c#,winforms,multithreading,callback,signals,C#,Winforms,Multithreading,Callback,Signals,很抱歉标题太长,我甚至不知道如何表达这个问题 我正在使用一个库,它从与主线程不同的上下文运行回调(是一个C库),我在C#中创建了回调,当调用回调时,我只想引发一个事件 但是,因为我不知道事件中会发生什么,我想找到一种方法来调用该方法,而不存在锁等问题(否则第三方用户将不得不在事件中处理此问题,非常难看) 有没有办法做到这一点? 我可能完全走错了路,但我正在考虑winforms处理不同线程的方式(调用.Invoke) 否则,我可以向窗口的消息循环发送消息,但我不太了解消息传递以及是否可以发送这样的

很抱歉标题太长,我甚至不知道如何表达这个问题

我正在使用一个库,它从与主线程不同的上下文运行回调(是一个C库),我在C#中创建了回调,当调用回调时,我只想引发一个事件

但是,因为我不知道事件中会发生什么,我想找到一种方法来调用该方法,而不存在锁等问题(否则第三方用户将不得不在事件中处理此问题,非常难看)

有没有办法做到这一点? 我可能完全走错了路,但我正在考虑winforms处理不同线程的方式(调用.Invoke)

否则,我可以向窗口的消息循环发送消息,但我不太了解消息传递以及是否可以发送这样的“自定义”消息

示例:

private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
    OnConfigure(EventArgs.Empty);
    return 0U;
}
这个回调是从另一个我无法控制的程序调用的,我想在主线程(处理我的winform的线程)中运行OnConfigure方法,如何执行? 或者换句话说,我希望运行OnConfigure而不必考虑锁

编辑1:

private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
    OnConfigure(EventArgs.Empty);
    return 0U;
}
我对这个例外有一个问题:

CallbackOnCollectedDelegate检索 消息:在代理“G19dotNet”上运行回调!G19dotNet.LgLcd+lgLcdOnSoftButtonsCB::Invoke“在垃圾收集器中收集”。在非托管代码期间,应确保在确保永远不会调用委托之前,不会删除委托

编辑2:

private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
    OnConfigure(EventArgs.Empty);
    return 0U;
}
问题由我自己解决,感谢Stackoverflow一直帮助我!
作为将来的参考:

在调用第三方函数之前,请获取对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.
        }));
    }
 }

如果您正在使用WinForms,并且希望在UI线程上执行某些操作,则需要在该线程上创建的某个控件(无论是
按钮
还是
表单
或其他控件)上调用
Invoke
BeginInvoke
。要执行此操作,您需要对其进行引用

例如,使用您的代码,并假设您有一个对名为
form
的表单的引用:

private uint lgLcdOnConfigureCB(int connection, System.IntPtr pContext)
{
    form.Invoke(new MethodInvoker(() => OnConfigure(EventArgs.Empty)));
    return 0U;
}

有一种模式叫做。链接的文章是关于如何使用它的一个很好的概述。类是这个模式的关键


此模式可能不完全适合您试图解决的问题,但它可能会让您对问题有一些了解。

请发布您正在做的工作的代码示例。检查问题,我添加了一个代码示例Dispatcher仅适用于WPF;他似乎在使用WinForms。@Adam Robinson:Dispatcher不仅适用于WPF,它还适用于控制台应用程序或WinForms。只需添加对System.Windows.Threading的引用即可。@Greg:Dispatcher不是设计用于处理WinForms的,即使它可以。但是,您不能以上述方式使用它
Dispatcher.CurrentDispatcher
仅在UI线程上运行该调用时返回正确的实例。为了使用它,您必须在UI线程上执行的代码中检索并存储
Dispatcher.CurrentDispatcher
的值。使用正确的线程同步机制,
Control.Invoke
Control.BeginInvoke
要简单得多。我知道这很愚蠢,但是。。。我找不到System.Windows.Threading(WindowsBase.dll),我应该为此命名空间引用什么?我找了很多,但是找不到。我正在使用.NET4.0。亚当·罗宾逊之后编辑:谢谢,我正在检查it@Adam:你是对的,但是我在OP编辑和WinForms之前回答了这个问题@火龙DoL:使用亚当斯的建议,它更适合WinForms。我将删除这个答案。这个设计模式非常有趣,我正在研究它,我非常喜欢进度条。