使用HttpWebRequest的死锁

时间:2016-05-24 17:10:10

标签: asynchronous httpwebrequest deadlock

我使用WebRequest创建了一个请求10次HTTP标头的异步方法。只要URL无效,我的程序运行正常。如果URL有效,则仅发送两个请求。

为了检查这个,我制作了两个按钮,一个用于检查有效的URL,一个用于检查无效的URL。如果我使用有效的URL,我的计数器将精确增加2,但仅限第一次。有趣的是,我仍然可以按下无效网址的按钮,它按预期工作。

这是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>

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

1 个答案:

答案 0 :(得分:1)

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

我们在这里找到了这个问题的提示 HttpWebResponse get stuck while running in a loop

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

添加dispose解决了问题:

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

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