Пользовательский интерфейс зависает при отправке нескольких httpclient или httpresponse - PullRequest
0 голосов
/ 18 апреля 2019

пытается получить источник страницы из списка URL. но это висит интерфейс. Я бы предпочел httpclient, чтобы я мог использовать один экземпляр. пожалуйста, дайте мне знать, что я могу сделать, чтобы он не зависал во время процесса.

    async Task AccessTheWebAsync(CancellationToken ct)
    {
        HttpClient client = new HttpClient();

        List<string> urlToSearch = UrlToSearchList();
        IEnumerable<Task<string>> downloadTasksQuery =from url in urlToSearch select ProcessURL2(url, client, ct);
        List<Task<string>> downloadTasks = downloadTasksQuery.ToList();

        while (downloadTasks.Count > 0)
        {
            Task<string> firstFinishedTask = await Task.WhenAny(downloadTasks);
            downloadTasks.Remove(firstFinishedTask);
            string length = await firstFinishedTask;
            resultsTextBox.Text += $"\r\nLength of the download:  {length}";
        }
    }

    private List<string> UrlToSearchList()
    {
        var urlToSearchList = new List<string>();
        foreach (var item in lbURLToSearch.Items)
        {
            urlToSearchList.Add(item.ToString());
        }
        return urlToSearchList;
    }

    async Task<string> ProcessURL2(string url, HttpClient client, CancellationToken ct)
    {
        HttpResponseMessage response = await client.GetAsync(url, ct);

        var contents = await response.Content.ReadAsStringAsync();
        return contents;
    }
    private void CancelButton_Click(object sender, EventArgs e)
    {
        if (cts != null)
        {
            cts.Cancel();
        }
    }

    private async void StartButton_Click(object sender, EventArgs e)
    {
        resultsTextBox.Clear();
        cts = new CancellationTokenSource();

        try
        {
            await AccessTheWebAsync(cts.Token);
            resultsTextBox.Text += "\r\nDownloads complete.";
        }
        catch (OperationCanceledException)
        {
            resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
        }
        catch (Exception)
        {
            resultsTextBox.Text += "\r\nDownloads failed.\r\n";
        }

        cts = null;
    }

Я также пробовал различные асинхронные методы. все равно результат тот же, зависает. ниже приведен один из асинхронных методов, которые я пробовал.

    private async void TsbtnStartURLScraper_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < lbURLToSearch.Items.Count; i++)
        {
            txtScrapeURL.Text = lbURLToSearch.Items[i].ToString();
            string urlAddress = lbURLToSearch.Items[i].ToString();
            var returnedresult = await DownloadStringV1(urlAddress);
            resultsTextBox.Text += returnedresult;
        }

    }
    public async Task<String> DownloadStringV1(String url)
    {
        // good code
        var request = await reusableHTTPClient.GetAsync(url);
        var download = await request.Content.ReadAsStringAsync();
        return download;
    }

ПРИМЕЧАНИЕ: что я пытаюсь сделать, это перебрать список URL-адресов и получить от них источник страницы. но когда я делаю это, это замораживает форму.

...