I'm trying to create an application that launches the GUI then AFTER it's already shown I want it to run another function that uses WebClient() and once it does it's query it's supposed to output to a label on the page. I've tried using on shown and a few other events but all of them stop the GUI from loading before it's finished making the query.
I've tried using a thread and it wouldn't allow updating the label since it was on a different thread, I tried async but couldn't manage to get results for some reason and now i'm in the middle of trying a background worker and I'm not getting any errors but the labels aren't getting updated either.
right now I have something that looks like this
public project()
{
InitializeComponent();
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += querysite;
}
private void querysite(object sender, DoWorkEventArgs e)
{
WebClient myWebClient = new WebClient();
myWebClient.Headers.Add("user-agent", "libcurl-agent/1.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
byte[] myDataBuffer = myWebClient.DownloadData("http://example.com/SystemStatus");
string download = Encoding.ASCII.GetString(myDataBuffer);
if (download.IndexOf("is online") !=-1)
{
systemStatusLabel.Text = "System is up";
}
else
{
systemStatusLabel.Text = "System is down!";
}
throw new NotImplementedException();
}
Is there something i'm doing wrong? Is there a better way to accomplish this? I've been stuck on this for a couple of hours and can't find anything that does what I need it to do.
I have modified your code a bit, to work with a BackgroundWorker
.
I have also allowed myself to do a bit of separation between the logic action of quering the site, and updating the GUI.
This should work for you:
public project()
{
InitializeComponent();
BackgroundWorker bw = new BackgroundWorker() { WorkerReportsProgress = true };
bool isOnline = false;
bw.DoWork += (sender, e) =>
{
//what happens here must not touch the form
//as it's in a different thread
isOnline = querysite();
};
bw.ProgressChanged += (sender, e) =>
{
//update progress bars here
};
bw.RunWorkerCompleted += (sender, e) =>
{
//now you're back in the UI thread you can update the form
if (isOnline)
{
systemStatusLabel.Text = "System is up";
}
else
{
systemStatusLabel.Text = "System is down!";
}
};
}
private bool querysite()
{
WebClient myWebClient = new WebClient();
myWebClient.Headers.Add("user-agent", "libcurl-agent/1.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
byte[] myDataBuffer = myWebClient.DownloadData("http://example.com/SystemStatus");
string download = Encoding.ASCII.GetString(myDataBuffer);
bool isOnline = download.IndexOf("is online") != -1;
return isOnline;
}
When you want the query to be done, you need to call bw.RunWorkerAsync();
.
You're trying to update something on the UI thread from a different thread, that won't work out. You can create a delegate to update the text though, this is a simple way to accomplish that.
this.Invoke((MethodInvoker) delegate { systemStatusLabel.Text = "System is up"; });
The asynchronous programming model with async
and await
provides and easy to understand and maintain way of coding.
There's no need for another asynchronous work manager (like the BackgroundWorker
) ohter than what's provided byt the language and conforming APIs.
Supposing some UI event is triggering the start of the work, all you have to do is:
private async void MyEvent(object sender, EventHandler e)
{
systemStatusLabel.Text = await GetSystemStatusAsync();
}
private async Task<string> GetSystemStatusAsync()
{
WebClient myWebClient = new WebClient();
myWebClient.Headers.Add("user-agent", "libcurl-agent/1.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
var myDataBuffer = await myWebClient.DownloadDataTaskAsync("http://example.com/SystemStatus");
string download = Encoding.ASCII.GetString(myDataBuffer);
if (download.IndexOf("is online") !=-1)
{
return "System is up";
}
else
{
return "System is down!";
}
}
Altough the new TaskAsync suffixed methods of the WebClient
conform to this new way of coding, I would recommend you to use the HttpClient which was developed with this new way of coding in mind.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.