I'm developing a plugin to Windows Forms app that diplays locations of terminals on the map (in WebBrowser control). The case is following:
- User clicks the button (calls the plugin);
- Async HTTP requests are created (determination of coordinates of terminals);
- As all the responses are recieved - the map should be diplayed to user.
I wrote the code:
foreach (var terminal in terminals)
{
var webRequest = (HttpWebRequest)WebRequest.Create(GeoCoder.GeoCodeUrl + terminal.Address);
var taskResp = Task.Factory.FromAsync<WebResponse>(webRequest.BeginGetResponse,
webRequest.EndGetResponse,
terminal.Id);
var taskResult = taskResp.ContinueWith(task =>
{
// Parse the response
});
runningTasks.Add(taskResult);
}
Task.WaitAll(runningTasks.ToArray()); // UI Thread blocks here!
webBrowser1.DocumentText = ...
It blocks UI thread as I have to wait until I get all the responses (coordinates) before I can display the map. I want to know how I can avoid that (without making a synchronous http requests)?
P.S. I know how to do it with async/await but cannot use them - I have to use .NET 4.0 and VS2010 - Microsoft.Bcl.Async cannot help).
You could use
System.Threading.ThreadPool.QueueUserWorkItem
to start your code which will run it on a separate thread to the UI but remember that you'll need to invokewebBrowser1.DocumentText = ...
as you'll get an exception if you won't. Hope this helps.As far as I can see you are struck with it how to do it in c# 4.0.
It is not that hard, keep in mind people used to do these kind of job in .Net 1.0 also, even before that :)
Am I missing something?
The BackgroundWorker class provides a casually easy way to perform work away from the UI thread. Perform your work in the .DoWork event handler, and upon completion, the UI thread is invoked to perform the .RunWorkerComplete eventhandler, in which you can update your UI with the map.