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

本文关键字:标签 窗体 文本 更新 处理 应用程序 另一个 线程 | 更新日期: 2023-09-27 18:32:07

我创建了一个线程来在我的应用程序中执行某些功能,在执行它时,我想更新用户可见的应用程序主形式的标签。

试图通过我调用 usinag 分隔线程的函数返回字符串数据,但它不起作用。

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

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;
    }
}

谢谢

内韦德

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

还可以考虑使用BackgroundWorker组件。

  1. 将背景工作者从"工具箱"拖到窗体中
  2. 将后台辅助角色的属性"辅助角色报告进度"设置为 true
  3. 订阅后台工作者事件 DoWork
  4. 订阅后台工作者事件 进度已更改

在 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); 
    }
}

在 ReportProgress 事件处理程序中,只需将值分配给标签:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    label1.Text = e.ProgressPercentage.ToString();
}

启动后台处理调用backgroundWorker1.RunWorkerAsync();

更新:您的代码不起作用,因为控件只能从创建它们的线程(UI 线程)更新。因此,您应该使用调用在 UI 线程上执行更新功能。您可以在此处找到示例和说明。

从你的线程中使用它:

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

编辑:

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

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