0

I am using System.Net.Http.HttpClient to make postaysnc request. While request is in progress I unplug the network cable, receive HttpRequestException. After some time plug the network cable again and make the postasync request, getting the HttpRequestException - sometimes i get the response server not available,sometimes timeout Do i need to dispose the httpclient on exception and recreate when the request is made? How to make the query successful on network restore.

    private async Task<string> GetServerResult()
    {
        try
        {
            var response = await myHttpClient.PostAsync("https://google.com", httpContent);
            response.EnsureSuccessStatusCode();
        }
        catch (HttpRequestException ex)
        {
            throw new HttpRequestException(ex.Message, ex.InnerException);
        }
    }
rags45
  • 23
  • 5
  • Possible duplicate of [Usage of EnsureSuccessStatusCode and handling of HttpRequestException it throws](https://stackoverflow.com/questions/21097730/usage-of-ensuresuccessstatuscode-and-handling-of-httprequestexception-it-throws) – Mark C. Nov 13 '18 at 16:57
  • my question is how to make the post async successful on network restore – rags45 Nov 13 '18 at 17:04
  • you need to add a retry logic in the code – Hassaan Nov 13 '18 at 17:07
  • I tried to add the retry logic, each time when post async request was called i was getting different excepttions - like server not able, server timeout – rags45 Nov 13 '18 at 17:08
  • i added a for loop and tried 3 times to retry , but retry was not successful. Is there any other way to do it – rags45 Nov 13 '18 at 17:10
  • Okay you need to create a queue based mechanism which works for you. This is a whole architectural solution. Could you share some of your requirements so we can discuss the architectural solution. – Hassaan Nov 13 '18 at 17:13
  • requirement is : post a request from WPF client to a server and server returns the result , update the result in the WPF browser control. in between if network connection is lost , throw the network error and when the network is restored if any query is posted, it should be successful. – rags45 Nov 13 '18 at 17:24

1 Answers1

0

As per your requirement, you have to change implement some sort of implementation in that case. My proposed solution is use to a caching mechanism at WCF Client and update it periodically.

The very simple implementation could be as: You have a very simple singleton class of and a periodic Timer fetches the data from your mentioned endpoint. It stores the last cached data so that you have a copy of the data and when the hits are failed you can configure a fallback mechanism for that. For instance you have an implementation like

//You single Cache class
public sealed class ClientCache
{
     #region Singleton implementation
     private static  ClientCache _clientCache = new ClientCache();


     private ClientCache()
     {

     }

     public static ClientCache Instance => _clientCache;    
     #endregion

     //Timer for syncing the data from Server
     private Timer _timer;
     //This data is the cached one
     public string data = string.Empty;

     internal void StartProcess()
     {
            //Initializing the timer
            _timer = new Timer(TimeSpan.FromMinutes(1).TotalMilliseconds); //This timespan is configurable
            //Assigning it an elapsed time event
            _timer.Elapsed += async (e, args) => await SyncServerData(e, args);
            //Starting the timer 
            _timer.Start();

     } 

     //In this method you will request your server and fetch the latest copy of the data
     //In case of failure you can maintain the history of the last disconnected server
     private async Task ProcessingMethod(object sender, ElapsedEventArgs e)
     {
         //First we will stop the timer so that any other hit don't come in the mean while
         timer.Stop();

         //Call your api here 
         //Once the hit is completed or failed 
         //On Success you will be updating the Data object
         //data = result from your api call  

         //Finally start the time again as
         timer.Start();
     } 

}

Now coming to Step two where to initialize the ClientCache Class. The best options are to initialize it in Global.asax class

protected void Application_Start()
{           
      //As
      ClientCache.Instance.StartProcess();
}

Now whenever your frontend calls the method you don't need to go back to the server. Just send back the result from your cache as:

private Task<string> GetServerResult()
{
     return Task.FromResult(ClientCache.Instance.data);
}
Hassaan
  • 3,931
  • 11
  • 34
  • 67