C#从本机线程修改UI

C#从本机线程修改UI,c#,multithreading,user-interface,delegates,pinvoke,C#,Multithreading,User Interface,Delegates,Pinvoke,让包含文本框和设置该文本框的方法的表单(以不安全的方式): 现在,如果我想使此线程安全,我需要执行以下操作: class Form { void SetTextBoxContent( String txt ) { if( this._tb_TextBox.InvokeRequired ) this._tb_TextBox.Invoke( new DelegateSetTextBoxContentUnsafe( SetTextBoxConte

让包含文本框和设置该文本框的方法的表单(以不安全的方式):

现在,如果我想使此线程安全,我需要执行以下操作:

class Form
{
    void SetTextBoxContent( String txt )
    {
        if( this._tb_TextBox.InvokeRequired )
            this._tb_TextBox.Invoke( new DelegateSetTextBoxContentUnsafe( SetTextBoxContentUnsafe );
        else
            this.DelagSetTextBoxContentUnsafe( txt );
    }

    delegate void DelegateSetTextBoxContentUnsafe( String txt );

    void SetTextBoxContentUnsafe( String txt )
    {
        this._tb_TextBox.SetText( txt );
    }
}
对吧??现在,如果我想让从本机线程调用SetTextBoxContent()成为可能,该怎么办?据我所知,无法调用对象的方法,因此我将把指向静态函数的指针传递到本机代码中。此函数将引用Form对象并自行执行方法调用:

class Form
{
    static Form instance;

    Form() { Form.instance = this }

    static void CallSetTextBoxContent( String txt )
    {
        Form.instance.SetTextBoxContent( txt );
    }

    void SetTextBoxContent( String txt )
    {
        if( this._tb_TextBox.InvokeRequired )
            this._tb_TextBox.Invoke( new DelagSetTextBoxContentUnsafe( SetTextBoxContentUnsafe );
        else
            this.DelagSetTextBoxContentUnsafe( txt );
    }

    delegate void DelagSetTextBoxContentUnsafe( String txt );

    void SetTextBoxContentUnsafe( String txt )
    {
        this._tb_TextBox.SetText( txt );
    }
}
现在我可以将静态函数CallSetTextBoxContent()传递到本机代码中吗? 我在某个地方读到,我需要为此创建一个委托。这意味着我需要为CallSetTextBoxContent()创建第二种类型的委托,并将该委托传递给本机代码?2个委托类型和3个函数来做一些简单但看起来有点混乱的事情。这条路对吗

谢谢:)


编辑:忘记提到我使用的是compact framework 2.0,请参见此处的示例:

您不必创建自己的委托。使用现有的<代码>操作应与方法的签名匹配。谢谢。看起来更干净,但是这个可以传递给本机代码吗?它和其他委托一样。您可以将其传递到本机代码,就像对其他代理一样。谢谢。我可以将从该函数获得的
IntPtr
用作本机代码中的常规函数指针吗?我忘了提到我使用的是标准的非托管C++。@ ViuS721是的,你可以。问问自己,这样用UI和非托管代码是否明智是明智的。使用静态的东西看起来有点脏,但是我看不出这有什么问题。我没有提到它,但是相同的非托管代码也在Android和JNI中使用,所以我还有其他一些限制。
class Form
{
    static Form instance;

    Form() { Form.instance = this }

    static void CallSetTextBoxContent( String txt )
    {
        Form.instance.SetTextBoxContent( txt );
    }

    void SetTextBoxContent( String txt )
    {
        if( this._tb_TextBox.InvokeRequired )
            this._tb_TextBox.Invoke( new DelagSetTextBoxContentUnsafe( SetTextBoxContentUnsafe );
        else
            this.DelagSetTextBoxContentUnsafe( txt );
    }

    delegate void DelagSetTextBoxContentUnsafe( String txt );

    void SetTextBoxContentUnsafe( String txt )
    {
        this._tb_TextBox.SetText( txt );
    }
}