Search code examples
c#.nethttpwebrequest

.NET HttpWebRequest Timeout Kills All Future Requests?


I have a program that has a lot of HttpWebRequest calls in it. It deals a lot with external API requests to various streaming platforms (Twitch, Hitbox, Beam, YouTube). All of my requests seem to work fine.

Here is an example of one of my requests:

private void save_Click(object sender, RoutedEventArgs e)
{
    string postUrl = "https://api.twitch.tv/kraken/channels/" + this.channelID;
    string postData = "channel[status]=" + Uri.EscapeDataString(status.Text) +
        "&channel[game]=" + Uri.EscapeDataString(game.Text);
    byte[] postByte = Encoding.UTF8.GetBytes(postData);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);

    request.Method = "PUT";
    request.Accept = "application/vnd.twitchtv.v5+json";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = postByte.Length;
    request.Headers.Add("Authorization", "OAuth " + password.Password);
    request.Headers.Add("Client-ID", this.clientID);
    request.Timeout = 15000;

    try
    {
        Stream putStream = request.GetRequestStream();
        putStream.Write(postByte, 0, postByte.Length);
        putStream.Close();

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    }
    catch (WebException err)
    {
        MessageBox.Show("Unable to update channel information:\n" + err.Message);
    }
}

However, there is an issue that if a request fails (such as a momentary internet hiccup), and the try-catch responds with an error due to a timeout, then no future HttpWebRequests will work until I restart my program.

This only happens if the error catch is initiated by a timeout.

Is there a reason why this happens and how can I fix it?


Solution

  • It's most likely being caused by resources that are not properly released causing locks.

    Change your code to maybe call abort on HttpWebRequest on WebException and maybe also wrap the HttpWebResponse and putStream in a using statement.

        private void save_Click(object sender, RoutedEventArgs e)
        {
            string postUrl = "https://api.twitch.tv/kraken/channels/" + this.channelID;
            string postData = "channel[status]=" + Uri.EscapeDataString(status.Text) +
                "&channel[game]=" + Uri.EscapeDataString(game.Text);
            byte[] postByte = Encoding.UTF8.GetBytes(postData);
    
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(postUrl);
    
            request.Method = "PUT";
            request.Accept = "application/vnd.twitchtv.v5+json";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = postByte.Length;
            request.Headers.Add("Authorization", "OAuth " + password.Password);
            request.Headers.Add("Client-ID", this.clientID);
            request.Timeout = 15000;
    
            try
            {
                using (Stream putStream = request.GetRequestStream())
                {
                    putStream.Write(postByte, 0, postByte.Length);
                    using (var response = (HttpWebResponse) request.GetResponse())
                    {
                        //assign the response result to a variable else it's getting disposed
                    }
                }
            }
            catch (WebException err)
            {
                request.Abort();
                MessageBox.Show("Unable to update channel information:\n" + err.Message);
            }
        }