0

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

我试图通过调用 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;
    }
}

谢谢,

纳维德

4

2 回答 2

2

从您的线程中使用它:

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

编辑:

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

private void UpdateLabel(string text)
{
    if (this.IsHandleCreated)
    {
        this.Invoke((MethodInvoker)delegate
        {
            label.Text = text;
        });
    }
    else
    {
        label.Text = text;
    }
}
于 2012-04-25T12:23:01.080 回答
2

还要考虑使用BackgroundWorker组件。

  1. 将 BackgroundWorker 从 ToolBox 拖到表单中
  2. 将 backgroundworker 的属性 WorkerReportsProgress 设置为 true
  3. 订阅 backgroundworker 的事件 DoWork
  4. 订阅 backgroundworker 的事件 ProgressChanged

在 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 线程)更新。因此,您应该使用 Invoke 在 UI 线程上执行更新功能。您可以在此处找到示例和说明。

于 2012-04-25T12:34:26.250 回答