Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 来自Warraper的winforms跨线程更新GUI_C#_Winforms - Fatal编程技术网

C# 来自Warraper的winforms跨线程更新GUI

C# 来自Warraper的winforms跨线程更新GUI,c#,winforms,C#,Winforms,我有两个类Data_Reader和Display_Data以及一个GUI表单。 我想要的是在文本框上显示data_Reader类的读取数据,该文本框存在于GUI_表单上,所以我编写了Display_data类来包装它。 但我有以下例外: 跨线程操作无效:控件“textBox1”是从创建它的线程以外的线程访问的 有人知道如何解决这个问题吗? 我只想更新GUI表单上的读取数据值 // Gui Form // ============ public partial class GUI_Fo

我有两个类Data_Reader和Display_Data以及一个GUI表单。 我想要的是在文本框上显示data_Reader类的读取数据,该文本框存在于GUI_表单上,所以我编写了Display_data类来包装它。 但我有以下例外:

跨线程操作无效:控件“textBox1”是从创建它的线程以外的线程访问的

有人知道如何解决这个问题吗? 我只想更新GUI表单上的读取数据值

//    Gui Form
//    ============
public partial class GUI_Form: Form
{
}
//    ==============
//    Display Data Class
//    ===========
public static class Display_Data
{
    public delegate void MyDelegate(Label myControl, string myArg2);
    public static void DelegateMethod(Label myControl, string myCaption)
        {
            myControl.Text = myCaption;
        } 
}

//=========================
//  Reader Class
//=========================
public void Data_Reader
{
    string Data_Received_text="Test";
    private System.ComponentModel.ISynchronizeInvoke _syn;
    Meter_Data_Class.packets_received_counter_status_display++;
    //it will call the display_Data class delegate method to update textbox on gui
    syn.BeginInvoke(new
                  Display_Data.MyDelegate(Display_Data.DelegateMethod),Data_Received_text);

}

使用textBox1.BeginInvoke调用委托。

不能直接从非UI线程的线程使用UI控件的方法或属性。 这就是为什么你会得到这个例外。 为了克服这个障碍,您需要从不同的线程调用一个委托,该线程将为您更改UI。 System.Windows.Forms命名空间中的控件类包含一个名为的属性,该属性告诉您当前线程是UI线程还是其他线程。 如果是UI线程,则可以使用控件的属性和方法。 如果不是UI线程,则必须调用委托才能使用控件的属性和方法。下面是一个基于您发布的代码中现有委托的简单方法:

public static void DelegateMethod(Label myControl, string myCaption)
    {
    // Calling from another thread? -> Use delegate
    if (myControl.InvokeRequired) {
        MyDelegate d = new MyDelegate(DelegateMethod);
        // Execute delegate in the UI thread, pass args as an array
        this.Invoke(d, new object[] {
            myControl,
            myCaption
        });
    // Same thread, assign string to the textbox
    } else {
        myControl.Text = myCaption;
    }
}

你能解释一下吗?那么为什么你在函数的开头设置myControl的Text属性,而你甚至不知道自己是否在同一个线程上?哎呀,谢谢你捕捉到了这一点。这是一个错误。我从vb.net中给别人的另一个答案中复制了这个答案,它一定是作为多个复制粘贴操作的剩余内容留在那里的。无论如何,我已经编辑了我的答案,删除了那个部分。