Reputation: 55
Trying to perform a number of HTTP Get requests in parallel, one per task. If I do the Gets through internet explorer they return almost instantaneously, but when calling in code through tasks, the first time I fire them off they take a good few seconds to return, but running a second time they return as I would expect. So either I'm doing something which is blocking something, or for some reason the threads are not starting? It's my first time trying to use TPL.
Here's the basic lookup class:
public class Lookup
{
public string Name { get; set; }
public string URL { get; set; }
public Lookup(string Name, string URL)
{
this.Name = Name;
this.URL = URL;
}
public LookupReturn DoLookup()
{
LookupReturn d = new LookupReturn();
d.Name = this.Name;
d.URL = this.URL;
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(this.URL);
Stream objStream;
objStream = wrGETURL.GetResponse().GetResponseStream();
StreamReader objReader = new StreamReader(objStream);
string sLine = objReader.ReadToEnd();
d.Result = sLine;
return d;
}
}
And the return type is simply:
public class LookupReturn
{
public string Name { get; set; }
public string Result { get; set; }
public string URL { get; set; }
}
So the attempt to run this in parallel - am testing from a Winforms GUI but eventually will be in a WCF service.
public partial class Form1 : Form
{
private List<Lookup> Lookups = new List<Lookup>();
private async void btnRunLookups_Click(object sender, EventArgs e)
{
Lookups.Add(new Lookup("Name1", "http://geturl1 "));
Lookups.Add(new Lookup("Name2", "http://geturl2 "));
// More lookups…
int workerThreads, complete;
ThreadPool.GetMinThreads(out workerThreads, out complete);
ThreadPool.SetMinThreads(100, complete);
btnRunLookups.Visible = false;
List <Task<LookupReturn>> lookupTasks = new List<Task<LookupReturn>>();
foreach(Lookup dl in Lookups)
{
lbLookups.Items.Add("Starting task for " + dl.URL);
Task<LookupReturn> t = new Task<LookupReturn>(() => dl.DoLookup() );
lookupTasks.Add(t);
t.Start();
}
//await Task.WhenAny(
// Task.WhenAll(lookupTasks.ToArray<Task<LookupReturn>>()),
// Task.Delay(3000)
// );
// This takes a good few seconds the first time
await Task.WhenAll(lookupTasks.ToArray<Task<LookupReturn>>());
// Now I need to see which ones completed and returned a result
foreach (var x in lookupTasks)
{
if (x.IsCompleted)
{
lbLookups.Items.Add(x.Result);
}
else
{
// lbLookups.Items.Add("Not finished " + x.Result.Name);
}
}
btnRunLookups.Visible = true;
}
Upvotes: 1
Views: 470
Reputation: 133995
Most likely the problem is that the program is doing some first-time setup stuff (DNS resolution, proxy detection, etc.) on the first call to GetResponse
. The proxy detection, in particular, can take a good long while.
Upvotes: 1
Reputation: 156524
Other people have noted that HttpWebRequest
can take a long time on its first request because it's looking for proxy information. Try setting its Proxy
property to null.
wrGETURL = WebRequest.Create(this.URL);
wrGETURL.Proxy = null;
Upvotes: 5