为什么选择Task.WaitAll();不等吗?

时间:2018-11-27 21:19:49

标签: c# html

我正在创建简单的网站抓取工具。我抓取网站的名称和链接,然后将其保存到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();
    }

1 个答案:

答案 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。绝对应该避免在单独的线程中写入resourcestaskz(因为它们都不是线程安全的)。

此外,您的代码正在返回:

temp = data.RequestMessage.RequestUri.ToString();

如果您唯一感兴趣的是URL,则根本不需要执行Web请求。您可以避免使用async / awaitTaskHttpClient等。您应该以同步方式直接将网址直接添加到List(因为将字符串添加到列表很快)。