Reputation: 127
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
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
Reputation: 236208
Also consider using BackgroundWorker
component.
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