我正在创建简单的网站抓取工具。我抓取网站的名称和链接,然后将其保存到txt文件中。 我的问题是使用Task.WaitAll()之后;我的控制台应用程序线程运行writeFile(),然后运行所有任务。 我的代码
static void Main(string[] args){
Console.WriteLine("Enter count of data!");
taskz = new List<Task>();
for (int i = 0; i < count; i++)
{
getSiteAsync();
}
var count = taskz.Count;
Task.WaitAll(taskz.ToArray());
writeFile();//This method gets execute before get links
Console.ReadLine();
}
getSite();
public static async Task getSiteAsync(){
var a = new Task(async () =>
{
back:
String temp = "";
var web = new HttpClient();
string url = "Random Links from web uploaded from file";
HttpResponseMessage data = await web.GetAsync(url);
temp = data.RequestMessage.RequestUri.ToString();
if (resources.Contains(temp) == false)
{
resources.Add(temp);//Add to list link
Console.WriteLine(temp);
}
else
{
goto back;
}
});
taskz.Add(a);
a.Start();
}
答案 0 :(得分:0)
当前代码要理解的关键是您正在等待错误的事情(请注意,IDE对此警告您-请注意getSiteAsync
下的弯曲行)。
您不是 WaitAll
是您明确创建的Task
个。由于在函数声明中使用了WaitAll
,因此您Task
正在幕后创建的“隐式” async
中。那些隐含的Task
(与您的a
Task
毫无关系)在您击中Task.WaitAll
时已经完成执行。
一种战术上的解决办法是:
public static Task getSiteAsync(){
var a = new Task(async () =>
{
back:
String temp = "";
var web = new HttpClient();
string url = "Random Links from web uploaded from file";
HttpResponseMessage data = await web.GetAsync(url);
temp = data.RequestMessage.RequestUri.ToString();
if (resources.Contains(temp) == false)
{
resources.Add(temp);//Add to list link
Console.WriteLine(temp);
}
else
{
goto back;
}
});
taskz.Add(a);
return a;
}
请注意,您应该考虑对您的方法进行更广泛的重新思考。例如,您可能希望完全避免使用Task.Run
(这可能涉及使用async
,但不是 Task.Run
)。您可能要避免使用goto
。绝对应该避免在单独的线程中写入resources
或taskz
(因为它们都不是线程安全的)。
此外,您的代码正在返回:
temp = data.RequestMessage.RequestUri.ToString();
如果您唯一感兴趣的是URL,则根本不需要执行Web请求。您可以避免使用async / await
,Task
,HttpClient
等。您应该以同步方式直接将网址直接添加到List
(因为将字符串添加到列表很快)。