none
HttpWebRequest/Resposne Callback Function never hit RRS feed

  • Question

  • I am trying to select json and a url from the database to make asycnh http posts.  However, the callback method (PostCallback) never gets hits.  When I step through the code in Visual Studio it does appear the callback method is getting hit.  I see everything getting sent and believe it is actually hitting the urls but never get anything executed in the callback.  Here is the code and the main Process method is called from within a Console app Main method.  Code is .NET 4.5.

    namespace Job
    {
        public class Program
        {
           
            static void Main(string[] args)
            {
                DateTime start = DateTime.Now;
                BLL.HttpPost.AllDone = new ManualResetEvent(false);
                try
                {
                    DateTime startDate = DateTime.Now.AddDays(-10);
                    DateTime endDate = DateTime.Now;
                    
                    BLL.HttpPost.Process(startDate, endDate);
                }
                catch (Exception ex)
                {
                    ErrorHandler.HandleError(ex);
                }

                finally
                {
                    // Keep the main thread from continuing while the asynchronous 
                    // operation completes. 
                    BLL.HttpPost.AllDone.WaitOne();
                    long latencyMS = (int)(DateTime.Now - start).TotalMilliseconds;
                    try
                    {
                        DAL.Data.UpdateTime(latencyMS);
                    }
                    catch (Exception ex)
                    {
                        ErrorHandler.HandleError(ex);
                    }
                }
            }
         }
    }

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Data;
    using System.Threading;
    using System.Net;
    using System.IO;

    namespace BLL
    {
        public static class HttpPost
        {
            public static System.Threading.ManualResetEvent AllDone = null;
            
            public static void Process(DateTime start, DateTime end)
            {            

                try
                {
                    DataSet data = DAL.Data.Select(start, end);
                    
                    for (int index = 0; index < data.Tables[0].Rows.Count; index++)
                    {
                        try
                        {
                            string json = data.Tables[0].Rows[index]["json"].ToString();
                            string url = data.Tables[0].Rows[index]["URL"].ToString();
                            long id = Convert.ToInt64(data.Tables[0].Rows[index]["ID"].ToString());
                            Post(url, json, id);
                        }
                        catch (Exception ex)
                        {
                            ErrorHandler.HandleError(ex);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ErrorHandler.HandleError(ex);
                }
                finally
                {
                    AllDone.Set();
                }
            }

            
            public static void Post(string url, string json, long id)
            {

                BOL.WebRequestState webRequestState = new WebRequestState();
                // Create a new HttpWebRequest object.
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.ContentType = "application/json";
                // Set the Method property to 'POST' to post data to the URI.
                request.Method = "POST";
                request.Timeout = 30000;

                webRequestState.StartTime = DateTime.Now;
                webRequestState.WebRequest = request;
                webRequestState.Id = id;
                webRequestState.Json = json;

                // start the asynchronous operation
                request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequestState);   
            }

            private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
            {

                BOL.WebRequestState webRequestState = (BOL.WebRequestState)asynchronousResult.AsyncState;

                // End the operation
                Stream postStream = webRequestState.WebRequest.EndGetRequestStream(asynchronousResult);

                string postData = webRequestState.Json;

                // Convert the string into a byte array. 
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);

                // Write to the request stream.
                postStream.Write(byteArray, 0, postData.Length);
                postStream.Close();

                // Start the asynchronous operation to get the response
                webRequestState.WebRequest.BeginGetResponse(new AsyncCallback(PostCallback), webRequestState);
            }
       

            public static void PostCallback(IAsyncResult asynchResult)
            {
                
                HttpWebResponse response = null;
                HttpWebRequest request = null;
                Stream streamResponse = null;
                StreamReader streamRead = null;
                BOL.WebRequestState webRequestState = null;
                int latency = 0;
                string statusMessage = string.Empty;

                try
                {
                    // State of request is asynchronous.
                    webRequestState = (BOL.WebRequestState)asynchResult.AsyncState;
                    request = webRequestState.WebRequest;
                    response = (HttpWebResponse)request.EndGetResponse(asynchResult);
                  

                    streamResponse = response.GetResponseStream();
                    streamRead = new StreamReader(streamResponse);
                    string responseString = streamRead.ReadToEnd();

                    dynamic jsonResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(responseString);

                    latency = (int)(DateTime.Now - webRequestState.StartTime).TotalMilliseconds;
                    
                    statusMessage = jsonResponse.Status.Value;


                }
                catch (Exception ex)
                {
                    statusMessage = "Unhandled Error";                
                    ErrorHandler.HandleError(ex);
                }
                finally
                {
                   try
                    {

                        DAL.Data.Update(webRequestState.Id, statusMessage, latency);
                    }
                    catch (Exception ex)
                    {
                        ErrorHandler.HandleError(ex);
                    }

                    if (streamResponse != null)
                        streamResponse.Close();

                    if (streamRead != null)
                        streamRead.Close();

                    if (response != null)
                        response.Close();

                    response = null;
                    request = null;

                }
            }

        }  
    }

    Wednesday, November 19, 2014 3:21 AM

Answers

  • Hello khitchcock,

    With your provided code, I made a test with it and reproduce this issue successfully. The BeginGetRequestStream callback is hit while the BeginGetResponse callback is not hit.

    Tthe caused reason I found is that the main thread finishes running before a thread to run the BeginGetResponse callback. So we need to give more time to let the new thread execute that callback method, one way is to hang up the main thread as using Console.Readline() below the HttpPost.Process method:

    DateTime start = DateTime.Now;
    
                    HttpPost.AllDone = new ManualResetEvent(false);
    
                    DateTime startDate = DateTime.Now.AddDays(-10);
    
                    DateTime endDate = DateTime.Now;
    
                    HttpPost.Process(startDate, endDate);
    
                    Console.ReadLine();//hang up the main thread.
    

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, November 20, 2014 2:43 AM
    Moderator