异步等待以及如何避免等待Task.Delay

时间:2018-07-15 21:11:56

标签: c# asp.net .net async-await

我正在尝试从一个网址检索100个页面。 网址的格式如下: https://www.someBlogSite.com/thread.php?t=xxxx&page=

因此,我的for循环基本上会遍历这些页面,并将结果存储在本地磁盘上的html文件中。

https://www.someBlogSite.com/thread.php?t=xxxx&page=1 https://www.someBlogSite.com/thread.php?t=xxxx&page=2 。 。 https://www.someBlogSite.com/thread.php?t=xxxx&page=99

这是我的工作代码,是否有一种避免使用await Task.Delay(10000)的方法?之所以必须使用它,是因为否则我的代码会在所有100页内容之前退出已被检索。

using System;
using System.Linq;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

namespace RetrieveImages
{

    public class PerformingGet

    {
        static void Main(string[] args) => MainAsync(args).Wait();

        static async Task MainAsync(string[] args)
        {
            //Instantiating HttpClient once in the main method since this is costly
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //Base Url--going forward only this will need to be edited per collection
            string pageBaseUrl = "https://www.someBlogSite.com/thread.php?t=xxxx&page=";
            var collectionOfUrls= new List<string>();

            for (int pageNum = 1; pageNum < 100; pageNum++)
            {
                string pageUrl = pageBaseUrl + pageNum;
                collectionOfUrls.Add(pageUrl);

            }

            var tasks = collectionOfUrls.Select(url => GetRequestString(client, url));

            var results = await Task.WhenAll(tasks);

            var text = string.Join("\r\n", results);
            WriteTextAsync(text);

            foreach (var x in collectionOfUrls)
            {
                Console.WriteLine(x);
                //await GetRequest(client, x);
            }

            Console.WriteLine("Task completed");
            await Task.Delay(10000);
        }


        async static Task<string> GetRequestString(HttpClient client, string Url)
        {
            using (HttpResponseMessage response = await client.GetAsync(Url))
            {
                if (response.IsSuccessStatusCode)
                {
                    using (HttpContent content = response.Content)
                    {
                        return await content.ReadAsStringAsync();
                    }
                }


                return string.Empty;
            }
        }


        static async void WriteTextAsync(string text)
        {
            // Set a variable to the My Documents path.
            string mydocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            // Write the text asynchronously to a new file named "WriteTextAsync.txt".
            using (StreamWriter outputFile = new StreamWriter(Path.Combine(mydocpath, "WriteTextAsync.html")))
            {
                await outputFile.WriteAsync(text);
            }
        }



    }
}

1 个答案:

答案 0 :(得分:2)

永远不要使用异步void(除非您真的知道自己在做什么,或者Visual Studio为您生成了一个异步void,例如事件处理程序)。如果您不需要从async方法返回任何内容,请使其返回Task(根本没有泛型类型参数)。您的代码实际上不必返回它;编译器会为您做到这一点。

static async Task WriteTextAsync(string text)
{
    string mydocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    using (StreamWriter outputFile = new StreamWriter(Path.Combine(mydocpath, "WriteTextAsync.html")))
    {
        await outputFile.WriteAsync(text);
    }
    //Notice no return statement
}

这将使您等待它,即使它没有返回值。

await WriteTextAsync(text);

如果您正在等待任务,那么最后不需要进行Task.Delay()调用。