C# 在应用程序处理另一个线程时更新主窗体标签中的文本

C# 在应用程序处理另一个线程时更新主窗体标签中的文本,c#,forms,label,desktop-application,C#,Forms,Label,Desktop Application,我已经创建了一个线程来执行应用程序中的某些功能,在执行该线程的同时,我希望更新应用程序主窗体中的标签,该标签对用户可见 我试图通过调用usinag seprate thread的函数返回字符串数据,但它不起作用 请告诉我是否有任何解决方案可以在使用线程执行活动时更新标签文本 class e2ertaData : e2erta1 { public void rsData() { network networkDetails = new network();

我已经创建了一个线程来执行应用程序中的某些功能,在执行该线程的同时,我希望更新应用程序主窗体中的标签,该标签对用户可见

我试图通过调用usinag seprate thread的函数返回字符串数据,但它不起作用

请告诉我是否有任何解决方案可以在使用线程执行活动时更新标签文本

class e2ertaData : e2erta1
{
    public void rsData()
    {
        network networkDetails = new network();
        csv csvFile = new csv();
        ftpFile ftpData = new ftpFile();
        //Host Geo Data
        string getIP = networkDetails.GetIP();
        string[] hostData = getIP.Split('~');
        GeoIP geoIPReq = new GeoIP();
        GeoIpData geoIPReqData = new GeoIpData();
        geoIPReqData = geoIPReq.GetMy();
        if (geoIPReqData.KeyValue["Error"].ToString() == "NO")
        {
            //Reading server names from XML file
            XmlDocument thisXmlDoc = new XmlDocument();
            thisXmlDoc.LoadXml(ftpData.getConfigFile("server.xml"));
            XmlNodeList xnList = thisXmlDoc.SelectNodes("/servers/server");
            //updating label in e2erta1

            this.l1.Text = "daaaaaaaaaaa";
            this.l1.Visible = true;
            this.l1.Refresh();
            foreach (XmlNode xn in xnList)
            {
                string rtNote = "";
                string requestedServer = xn["sname"].InnerText;
                string rtGet = networkDetails.GetRT(requestedServer);
                if (rtGet.Contains("Exception"))
                {
                    rtNote = rtGet;
                    //MessageBox.Show(rtNote);
                }
                try
                {
                    var row = new List<string> { rtGet, rtNote };
                    ftpData.addToCSVFile(row);
                }
                catch (Exception c)
                {
                    MessageBox.Show(c.ToString());
                }
            }
        }
        else
        {
            MessageBox.Show("Geo data : " + geoIPReqData.KeyValue["Error"].ToString());
        }
        //return null;
    }
}
e2ertaData类:e2erta1
{
公共数据()
{
网络详细信息=新网络();
csv csvFile=new csv();
ftpFile ftpData=新的ftpFile();
//宿主地理数据
字符串getIP=networkDetails.getIP();
字符串[]hostData=getIP.Split('~');
GeoIP geoIPReq=新的GeoIP();
GeoIpData geoIPReqData=新的GeoIpData();
geoIPReqData=geoIPReq.GetMy();
if(geoIPReqData.KeyValue[“错误”].ToString()=“否”)
{
//从XML文件读取服务器名称
XmlDocument thisXmlDoc=新的XmlDocument();
thisXmlDoc.LoadXml(ftpData.getConfigFile(“server.xml”);
XmlNodeList xnList=thisXmlDoc.SelectNodes(“/servers/server”);
//更新e2erta1中的标签
this.l1.Text=“daaaaaaaaa”;
this.l1.Visible=true;
这个.l1.Refresh();
foreach(xnList中的XmlNode xn)
{
字符串rtNote=“”;
string requestedServer=xn[“sname”].InnerText;
字符串rtGet=networkDetails.GetRT(requestedServer);
if(rtGet.Contains(“异常”))
{
rtNote=rtGet;
//MessageBox.Show(rtNote);
}
尝试
{
var row=新列表{rtGet,rtNote};
ftpData.addToCSVFile(行);
}
捕获(例外c)
{
Show(c.ToString());
}
}
}
其他的
{
MessageBox.Show(“地理数据:+geoIPReqData.KeyValue[“Error”].ToString());
}
//返回null;
}
}
谢谢


Naveed

从您的线程中使用此选项:

this.Invoke((MethodInvoker)delegate
{
    label.Text = "...";
});
编辑:

您还可以在使用
Invoke
之前测试属性:

private void UpdateLabel(string text)
{
    if (this.IsHandleCreated)
    {
        this.Invoke((MethodInvoker)delegate
        {
            label.Text = text;
        });
    }
    else
    {
        label.Text = text;
    }
}

从您的线程中使用此选项:

this.Invoke((MethodInvoker)delegate
{
    label.Text = "...";
});
编辑:

您还可以在使用
Invoke
之前测试属性:

private void UpdateLabel(string text)
{
    if (this.IsHandleCreated)
    {
        this.Invoke((MethodInvoker)delegate
        {
            label.Text = text;
        });
    }
    else
    {
        label.Text = text;
    }
}

也可以考虑使用<代码>后台工作人员< /COD>组件.< /P>

  • 将BackgroundWorker从工具箱拖到窗体中
  • 将backgroundworker的属性WorkerReportsProgress设置为true
  • 订阅backgroundworker的活动工作
  • 订阅backgroundworker的事件进度更改
  • 在DoWork事件处理程序中,运行线程中的所有操作,并调用ReportProgress方法将进度传递给窗体:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // reading server names from XML file        
    
        for (int i = 0; i < xnList.Count; i++)
        {
            XmlNode xn = xnList[i];
            // process node
    
            // report percentage to UI thread
            int percentProgress = (i+1)*100/xnList.Count;
            backgroundWorker1.ReportProgress(percentProgress); 
        }
    }
    
    要启动后台处理,请调用backgroundWorker1.RunWorkerAsync()


    更新:您的代码无法工作,因为只能从创建控件的线程(UI线程)更新控件。所以您应该使用Invoke在UI线程上执行更新功能。你可以找到的例子和描述。

    也考虑使用<代码>后台工作人员< /Cult>组件> < /P>

  • 将BackgroundWorker从工具箱拖到窗体中
  • 将backgroundworker的属性WorkerReportsProgress设置为true
  • 订阅backgroundworker的活动工作
  • 订阅backgroundworker的事件进度更改
  • 在DoWork事件处理程序中,运行线程中的所有操作,并调用ReportProgress方法将进度传递给窗体:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // reading server names from XML file        
    
        for (int i = 0; i < xnList.Count; i++)
        {
            XmlNode xn = xnList[i];
            // process node
    
            // report percentage to UI thread
            int percentProgress = (i+1)*100/xnList.Count;
            backgroundWorker1.ReportProgress(percentProgress); 
        }
    }
    
    要启动后台处理,请调用backgroundWorker1.RunWorkerAsync()


    更新:您的代码无法工作,因为只能从创建控件的线程(UI线程)更新控件。所以您应该使用Invoke在UI线程上执行更新功能。您可以找到的示例和说明。

    请尝试label.Refresh(),也可以尝试一些codetry label.Refresh()以及一些codeInvoke或BeginInvoke,在创建窗口句柄之前,不能对控件调用。发布一些代码。您还可以在使用
    Invoke
    之前测试属性。在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke。发布部分代码。您也可以在使用
    Invoke
    之前测试属性。谢谢,我查看了您共享的示例以解决我的问题。谢谢,我查看了您共享的示例以解决我的问题。