загрузить исходный код http с помощью асинхронной задачи httpclient - PullRequest
0 голосов
/ 16 мая 2019

пытается загрузить / получить страницу html-кода, используя код ниже, найденный на https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/how-to-extend-the-async-walkthrough-by-using-task-whenall

, пытающийся учиться и очень новый.я попытался изменить кое-что, что не сработало.

    private async void startButton_Click(object sender, RoutedEventArgs e)  
    {  
        resultsTextBox.Clear();  

        // One-step async call.  
        await SumPageSizesAsync();  

        // Two-step async call.  
        //Task sumTask = SumPageSizesAsync();  
        //await sumTask;  

        resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";  
    }  

    private async Task SumPageSizesAsync()  
    {  
        // Make a list of web addresses.  
        List<string> urlList = SetUpURLList();  

        // Declare an HttpClient object and increase the buffer size. The  
        // default buffer size is 65,536.  
        HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };  

        // Create a query.  
        IEnumerable<Task<int>> downloadTasksQuery =   
            from url in urlList select ProcessURLAsync(url, client);  

        // Use ToArray to execute the query and start the download tasks.  
        Task<int>[] downloadTasks = downloadTasksQuery.ToArray();  

        // You can do other work here before awaiting.  

        // Await the completion of all the running tasks.  
        int[] lengths = await Task.WhenAll(downloadTasks);  

        //// The previous line is equivalent to the following two statements.  
        //Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);  
        //int[] lengths = await whenAllTask;  

        int total = lengths.Sum();  

        //var total = 0;  
        //foreach (var url in urlList)  
        //{  
        //    // GetByteArrayAsync returns a Task<T>. At completion, the task  
        //    // produces a byte array.  
        //    byte[] urlContent = await client.GetByteArrayAsync(url);  

        //    // The previous line abbreviates the following two assignment  
        //    // statements.  
        //    Task<byte[]> getContentTask = client.GetByteArrayAsync(url);  
        //    byte[] urlContent = await getContentTask;  

        //    DisplayResults(url, urlContent);  

        //    // Update the total.  
        //    total += urlContent.Length;  
        //}  

        // Display the total count for all of the web addresses.  
        resultsTextBox.Text +=  
            $"\r\n\r\nTotal bytes returned:  {total}\r\n";
    }  

    private List<string> SetUpURLList()  
    {  
        List<string> urls = new List<string>   
        {   
            "https://msdn.microsoft.com",  
            "https://msdn.microsoft.com/library/hh290136.aspx",  
            "https://msdn.microsoft.com/library/ee256749.aspx",  
            "https://msdn.microsoft.com/library/hh290138.aspx",  
            "https://msdn.microsoft.com/library/hh290140.aspx",  
            "https://msdn.microsoft.com/library/dd470362.aspx",  
            "https://msdn.microsoft.com/library/aa578028.aspx",  
            "https://msdn.microsoft.com/library/ms404677.aspx",  
            "https://msdn.microsoft.com/library/ff730837.aspx"  
        };  
        return urls;  
    }  

    // The actions from the foreach loop are moved to this async method.  
    async Task<int> ProcessURLAsync(string url, HttpClient client)  
    {  
        byte[] byteArray = await client.GetByteArrayAsync(url);  
        DisplayResults(url, byteArray);  
        return byteArray.Length;  
    }  

    private void DisplayResults(string url, byte[] content)  
    {  
        // Display the length of each web site. The string format   
        // is designed to be used with a monospaced font, such as  
        // Lucida Console or Global Monospace.  
        var bytes = content.Length;  
        // Strip off the "https://".  
        var displayURL = url.Replace("https://", "");  
        resultsTextBox.Text += $"\n{displayURL,-58} {bytes,8}";
    }

РЕДАКТИРОВАТЬ -

этот код взят по ссылке, которую я разместил, я проверилкод, он возвращает байт / длину содержимого.но я хотел бы, чтобы источник страницы вместо информации байта / длины.я попытался, изменив функцию processurlasync и смог получить HTML источник.но это правильный способ сделать это и самый эффективный способ сделать это?

    async Task<int> ProcessURLAsync(string url, HttpClient client)
    {
        byte[] byteArray = await client.GetByteArrayAsync(url);
        //DisplayResults(url, byteArray);
        return byteArray.Length;
    }
    async Task<string> ProcessURLAsyncS(string url, HttpClient client)
    {
        var byteArrayS = new StreamReader(await client.GetStreamAsync(url));
        //byte[] byteArray = await client.GetByteArrayAsync(url);
        DisplayResults(url, byteArrayS.ReadToEnd());
        return byteArrayS.ReadToEnd();
    }

1 Ответ

0 голосов
/ 17 мая 2019

Несколько вещей:

  • Если вы хотите сделать запрос GET и прочитать содержимое в виде строки, просто используйте GetStringAsync:

    string content = await client.GetStringAsync(url);
    
  • Будьте внимательны при чтении всего содержимого в одну строку. Это может быть много памяти, чтобы потреблять. Причина использования GetStreamAsync вместо этого состоит в том, чтобы читать из потока порциями и записывать этот вывод в другом месте.

  • Пример кода, который вы привели, довольно старый и допускает некоторые ошибки:

    1. Размер буфера по умолчанию составляет 2 ГБ , а не 64 КБ. В большинстве случаев нет необходимости устанавливать его явно.

    2. HttpClient предназначен для создания в виде отдельного экземпляра и общего доступа , а не для каждого запроса (или для каждого нажатия кнопки в этом случае).

    3. Строка, которая вызывает downloadTasksQuery.ToArray(), не нужна. Как только вы начнете ожидать задачи, они начнутся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...