我想避免由于并行for循环和httpclient导致的应用程序崩溃问题,但由于编程知识有限,我无法应用Web上其他位置提供的解决方案。我的代码粘贴在下面。Parallel.For和httpclient崩溃应用程序C#
class Program
{
public static List<string> words = new List<string>();
public static int count = 0;
public static string output = "";
private static HttpClient Client = new HttpClient();
public static void Main(string[] args)
{
//input path strings...
List<string> links = new List<string>();
links.AddRange(File.ReadAllLines(input));
List<string> longList = new List<string>(File.ReadAllLines(@"a.txt"));
words.AddRange(File.ReadAllLines(output1));
System.Net.ServicePointManager.DefaultConnectionLimit = 8;
count = longList.Count;
//for (int i = 0; i < longList.Count; i++)
Task.Run(() => Parallel.For(0, longList.Count, new ParallelOptions { MaxDegreeOfParallelism = 5 }, (i, loopState) =>
{
Console.WriteLine(i);
string link = @"some link" + longList[i] + "/";
try
{
if (!links.Contains(link))
{
Task.Run(async() => { await Download(link); }).Wait();
}
}
catch (System.Exception e)
{
}
}));
//}
}
public static async Task Download(string link)
{
HtmlAgilityPack.HtmlDocument document = new HtmlDocument();
document.LoadHtml(await getURL(link));
//...stuff with html agility pack
}
public static async Task<string> getURL(string link)
{
string result = "";
HttpResponseMessage response = await Client.GetAsync(link);
Console.WriteLine(response.StatusCode);
if(response.IsSuccessStatusCode)
{
HttpContent content = response.Content;
var bytes = await response.Content.ReadAsByteArrayAsync();
result = Encoding.UTF8.GetString(bytes);
}
return result;
}
}
有例如this one的解决方案,但我不知道如何把await
关键字在我的主要方法,目前该程序简单地退出,因为它缺乏Task.Run()
之前。正如你所看到的,我已经应用了一个关于async Download()
方法的解决方法,以main方法调用它。 我也怀疑在不同的并行线程中使用同一个httpclient实例。请告诉我我是否应该每次创建httpclient的新实例。
谢谢。我使用另一个包中的异步foreach循环来解决它(使用类似问题的其他答案之一)。在为每个新的线程调用使用一个新的http客户端实例后,我观察到速度的显着提高。 –
嗯。我非常怀疑HttpClient的许多实例是加速的原因。其他东西必须有所不同。我会告诫你,你所做的并不是最佳的,但如果你不[用尽套接字](https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)我想没关系。 –