You can't speed-up things much because bottleneck is your Internet connection. However there is something you can do:
1) Do not LINQ count lines, it's an array and its size is known (micro optimization, you won't ever notice this change).
2) Use using
to release disposable objects (nothing to do with speed, better error handling: if something went wrong with your code you'll release resources with GC).
3) Make them parallel. This will speed-up things little bit:
private void button4_Click(object sender, EventArgs e)
{
var lines = File.ReadAllLines(@"c:\data\temp.txt");
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(lines, options, line =>
{
var request = WebRequest.Create(line);
using (var response = request.GetResponse())
{
var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII);
// Do your stuff
BeginInvoke(new MethodInvoker(delegate
{
textBox1.Text += ".";
}));
}
});
}
Few more notes:
MaxDegreeOfParallelism
sets maximum number of concurrent requests. Multiple active concurrent connections won't speed-up things indefinitely and they may even slow things down. Some trials will help you to set this value to a reasonable value.
There is not any error checking but network things may temporary go wrong but after a short delay they may work as expected. I suggest to also read System.Net.WebException: The remote name could not be resolved and this for I/O operations.
To make it a more complete example, your click even handler will be:
private void button4_Click(object sender, EventArgs e)
{
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(ReadUrlList(@"c:\data\temp.txt"), options, ProcessUrl);
}
Actual code to process each URL and to read URL list:
private static string[] ReadUrlList(string path)
{
return File.ReadAllLines(@"c:\data\temp.txt");
}
private void ProcessUrl(string url)
{
ProcessResponse(response =>
{
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
{
// Do your stuff
// We're working on separate threads, to access UI we
// have to dispatch the call to UI thread. Note that
// code will be executed asynchronously then local
// objects may have been disposed!
BeginInvoke(new MethodInvoker(delegate
{
textBox1.Text += ".";
}));
}
});
}
With this helper method to hide try/wait pattern for network operations:
private static void ProcessResponse(string url, Action<WebResponse> action)
{
for (int i=1; i <= NumberOfRetries; ++i)
{
try
{
var request = WebRequest.Create(line);
using (var response = request.GetResponse())
{
action(response);
}
break;
}
catch (Exception e)
{
if (i == NumberOfRetries)
throw;
Thread.Sleep(DelayOnRetry);
}
}
}
private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;