使用 HttpWebRequest 的死锁

Deadlock using HttpWebRequest

我创建了一个使用 WebRequest 请求 10 次 HTTP header 的异步方法。只要 URL 无效,我的程序就可以正常工作。 URL 是否有效,只发送两个请求。

为了检查这一点,我制作了两个按钮,一个用于检查有效 URL,一个用于检查无效 URL。如果我使用有效的 URL,我的计数器正好增加 2,但只是第一次。有趣的是,我仍然可以按下无效 URL 的按钮并且它按预期工作。

这是cs文件:

public partial class MainWindow : Window
{
    int counter = 0;

    private async Task DoWork(String url)
    {
        for (int i = 0; i < 10; i++)
        {
            HttpWebRequest request = WebRequest.CreateHttp(url);
            request.Method = "HEAD";
            request.Timeout = 100;

            HttpWebResponse response = null;

            try
            {
                response = (HttpWebResponse)await request.GetResponseAsync();
            }
            catch(Exception ex)
            {

            }

            counter++;
            Dispatcher.Invoke(() => label.Content = counter);
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        DoWork("http://www.google.ch");
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        DoWork("http://www.adhgfqliehfvufdigvhlnqaernglkjhr.ch");
    }
}

这是 xaml 文件

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Label Name="label" Content="Label" HorizontalAlignment="Left" Margin="78,151,0,0" VerticalAlignment="Top"/>
        <Button Content="Valid URL" HorizontalAlignment="Left" Margin="64,71,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Button Content="Invalid URL" HorizontalAlignment="Left" Margin="144,71,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
    </Grid>
</Window>

有人可以解释这种行为吗?

由于异步方法,问题不是预期的死锁。这是因为我没有使用处理 HttpWebResponse。

这里我们找到了这个问题的提示

也解释了为什么它正好工作了两次。连接似乎保持打开状态并且有一个 ConnectionLimit: System.Net.ServicePointManager.DefaultConnectionLimit

添加 dispose 解决了问题:

            try
            {
                response = (HttpWebResponse)await request.GetResponseAsync();
            }
            catch (Exception ex)
            {

            }
            finally
            {
                if (response != null)
                {
                    response.Dispose();
                }
            }