I have a listview which I populate from a webservice query. Problem is that if the http query is slow due to network or the URL is wrong then the query freezes the UI for a bit. So my question is how do I throw this off to a side process and populate the list in the background?
Here is how I get the data and it usually sits for 30 secs or more at request.GetResponse(); I get JSON back and parse that but this function is the hold up and would like to wrap it in something. So how would I do that specifically?
public static String get(String url) {
StringBuilder sb = new StringBuilder();
// used on each read operation
byte[] buf = new byte[32768];
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Timeout = 10000;
HttpWebResponse response;
try {
response = (HttpWebResponse)request.GetResponse();
} catch (WebException we) {
return "ERROR!"
}
Stream resStream = response.GetResponseStream();
... read from stream and parse
}
#### Using suggestion of Worker Thread ############
This doesn’t work either.
// create new thread
new Thread(new ThreadStart(myTable) ).Start();
inside the myTable method using an anonymous delegate I thought might be the best way.
private void myTable() {
if (this.InvokeRequired) {
this.Invoke(new EventHandler(delegate(object obj, EventArgs a) {
// do work here
String url = "http://someurl....";
// Set the view to show details.
listView1.View = View.Details;
// Display check boxes.
listView1.CheckBoxes = false;
// Select the item and subitems when selection is made.
listView1.FullRowSelect = true;
listView1.Items.Clear();
listView1.Columns.Clear();
listView1.Columns.Add(Resources.MainColumn0, 20, HorizontalAlignment.Left);
listView1.Columns.Add(Resources.MainColumn1a, 250, HorizontalAlignment.Left);
listView1.Columns.Add(Resources.MainColumn2, 150, HorizontalAlignment.Left);
try {
// Call the function mentioned above to get the data from the webservices....
string users = get(urlUsers);
.............
Use a worker thread to make the query, the use Control.Invoke to update the UI or use an async call to get the data from the service. Without knowing more about exactly how you’re getting the data and doing population, that’s about as detailed as I can get.
EDIT
Your attempt at offloading the work to a thread is subverted by your call to Invoke, which moves everything back to the UI thread. You need to do something along these lines:
Note that the long-running part of the command is not contained within the Invoke call.