Naveed Qamar
Naveed Qamar

Reputation: 127

Update text in the label of main form while application is processing an another thread

I have created a thread to perform certain functionality in my application and while performing it I want to update the label in the main form of the application which is visible to user.

I tried to return the string data through the function which I am calling usinag seprate thread but it does not work.

Please let me know if there is any solution to update the label text while performing an activity using 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;
    }
}

Thanks,

Naveed

Upvotes: 0

Views: 9391

Answers (2)

david.s
david.s

Reputation: 11403

Use this from your thread:

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

Edit:

You can also test the IsHandleCreated property before using Invoke:

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

Upvotes: 2

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236208

Also consider using BackgroundWorker component.

  1. Drag BackgroundWorker from ToolBox to your form
  2. Set backgroundworker's property WorkerReportsProgress to true
  3. Subscribe to backgroundworker's event DoWork
  4. Subscribe to backgroundworker's event ProgressChanged

Inside DoWork event handler run all what you do in your thread, and call ReportProgress method to pass progress to your form:

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

Inside ReportProgress event handler simply assign value to label:

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

To start background processing call backgroundWorker1.RunWorkerAsync();

UPDATE: Your code is not working, because controls could be updated only from thread which created them (UI thread). So you should use Invoke to execute update functionality on UI thread. Example and description you can find here.

Upvotes: 2

Related Questions