Cannot access a disposed object. ‘System.Net.Http.StringContent’ While having retry logic.

Hi,

I faced this scenario today when I was trying to make an HttpPost call using a retry logic wherein I was getting an ObjectDisposedException while trying to retry for the first time.

Exception Message:

Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'

My calling code was something like this.

var httpContent = GetHttpContent();

retryPolicy.ExecuteWithRetry(async () => await httpClient.PostAsync(url, httpContent));

The problem with this code is, when the first call to PostAsync is made and it fails, the httpContent object is disposed. This is as designed in the HttpClient class. Refer the comment in this method. Although this seems odd, they intent to do this so that the user doesn’t have to do this explicitly and also to avoid the same request being Posted more than once.

So what happens is, when the first call fails, httpContent is disposed, then as we have retry mechanism, it tries to make the post call again, now with a disposed object and hence this time, the call fails with an ObjectDisposedException.

An easy way to resolve this is to NOT use a variable to store httpContent and instead, create http content directly while making the call. Something like this.

retryPolicy.ExecuteWithRetry(async () => await httpClient.PostAsync(url, GetHttpContent()));

This will make sure that every subsequent retry has a new httpContent object created.

Hope this helps!

References:

  1. http://stackoverflow.com/questions/19260060/retrying-httpclient-unsuccessful-requests
  2. http://stackoverflow.com/questions/29369945/objectdisposedexception-on-httpclient
  3. http://stackoverflow.com/a/15708633/2377928
  4. http://stackoverflow.com/a/25495500/2377928
  5. https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpClient.cs
  6. https://github.com/dotnet/corefx/issues/1794
Advertisements

Invoke a POST method with XML Request message in C#

Hi,

To invoke a POST method located at a particular URL with an XML request message, we need to follow the below steps:

  1. Create a request to the url
  2. Put required request headers
  3. Convert the request XML message to a stream (or bytes)
  4. Write the stream of bytes (our request xml) to the request stream
  5. Get the response and read the response as a string

This looks much easier when seen in code. 🙂 Keep reading…..

So, the code for the above steps looks something like this:

namespace HttpPostRequestDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string xmlMessage = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" +
            "construct your xml request message as required by that method along with parameters";
            string url = "http://XXXX.YYYY/ZZZZ/ABCD.aspx";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);


            byte[] requestInFormOfBytes = System.Text.Encoding.ASCII.GetBytes(xmlMessage);
            request.Method = "POST";
            request.ContentType = "text/xml;charset=utf-8";
            request.ContentLength = requestInFormOfBytes.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(requestBytes, 0, requestInFormOfBytes.Length);
            requestStream.Close();


            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader respStream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);
            string receivedResponse = respStream.ReadToEnd();

            Console.WriteLine(receivedResponse);
            respStream.Close();
            response.Close();
        }
    }
}

If the xmlMessage is formed correctly, then you should be getting the expected response from the web method located at the URL.

Hope this helps!

Restricting to only one running instance of an application in C#

Hi,

We all must have observed some time or the other that when you try to open an application that is already running, you get a pop up that says, “Another instance of the same application is already running” or something like that.

This post will show how you can implement that in your windows application using C#.

The main class used here is the Process class that is a part of System.Diagnostics namespace. Process class provides access to some local and also remote processes and can be used to start/stop these processes. Some static methods provided by Process class are GetCurrentProcess() and GetProcessesByName(string process_name).

These methods pretty much do exactly what they are named.

  • GetCurrentProcess() basically gets a Process component and links it to the current running process from which this method was called. That means that if we call this method from our app (which is what we’ll do shortly), the method returns a Process component that is linked to our app’s process.
  • GetProcessesByName(string process_name) returns an array of Process components that are currently running in the local system with the specified process name, process_name. So for example, if you have chrome browser running with multiple tabs open, then you can see in Task Manager that there are as many number of “Chrome.exe” processes running as there are tabs in your browser. Now if you call this method for “Chrome.exe”, you will get an array of Process components each having all the details of one chrome.exe process each.

NOTE : It is very important to note here that these methods simply GET the already existing and running instances of the processes. They DO NOT create new instances of Process class. Note the words “gets/returns” in the above bullet points.

So to implement this functionality, all you need to do is before you create a new instance of your application, get all the running processes and check the names of those processes with the currently running process. If you find such a process, it means that there is an instance already running and you should not create another instance for the same application. If not, just create a new instance for the application.

Check the below code. I have created a Windows Forms application with a very basic form with a label. In the Program.cs file, I have created a static method that performs the above mentioned check and returns either true or false based on whether it finds a process with the same name or not.

[STAThread]
 static void Main()
 {
     if (AnotherInstanceExists())
     {
           MessageBox.Show("You cannot run more than one instance of this application.", "Only one instance allowed to run", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
           
           return;
     }

     Form1 objMyForm = new Form1();
     objMyForm.ShowDialog();
 }
public static bool AnotherInstanceExists()
{
    Process currentRunningProcess = Process.GetCurrentProcess();
    Process[] listOfProcs = Process.GetProcessesByName(currentRunningProcess.ProcessName);
 
    foreach (Process proc in listOfProcs)
    {
       if ((proc.MainModule.FileName == currentRunningProcess.MainModule.FileName) && (proc.Id != currentRunningProcess.Id))
               return true;
    }
    return false;
 }

The method AnotherInstanceExists() initially makes a call to GetCurrentProcess() to get a Process component associated with the currently running process. Then it makes a call to GetProcessesByName() and passes the currently running process’s name as parameter. With the array of Process components that are returned from this method, it checks whether the current process ID and process module’s filename are the same. Basically it checks whether both these processes are same or not.

If the method returns true, the user is shown an error message that only one instance can be running for this application.

That’s all there is to do.

Hope this helps!

[Solution]configuration system failed to initialize – C# Exception

Hi,

Today I encountered an exception while working on an application. The exception was “configuration system failed to initialize”. The problem that I was having in my application configuration file was that I declared the <appSettings> tag immediately after the root tag <configuration>.

The schema of a configuration file mandates the “<configSections>” tag to be the first child of the root tag. Thus, if you put any other tag as the first child of root <configuration> tag, the application would throw an exception. So, ALWAYS, the <configSections> tag should immediately follow root <configuration> tag.

Correct Format:

<?xml version="1.0"?>
<configuration>
   <configSections>
      <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
          <section name="your_project_name.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </sectionGroup>

Wrong Format:

<?xml version="1.0"?>
<configuration>
   <appSettings>
       ...
       ...
       ...
   </appSettings>
   <configSections>
      .....
    </configSections>

This is just one of the reasons for which the exception is thrown. There are more than one reasons for it. For me, this solution worked out. Hope it works out to you as well! 🙂

Hope this helps!!

Getting a machine name of logged in user in asp.net

Hi,

I recently encountered this scenario and thought of blogging about it. To get the machine name of the logged in user, you can use the “GetHostEntry()” method provided in System.Net.Dns class.

GetHostEntry takes a string as parameter and it is the hostname or address of the machine whose entry we need to get. So in order to get the machine name, we need to make use of the server variable remote_addr.

GetHostEntry returns an IPHostEntry object and its HostName property would give the machine name of the logged in user. So the line of code would be

System.Net.Dns.GetHostEntry(Request.ServerVariables["REMOTE_ADDR"]).HostName;

 

Hope this helps!

How to implement a multi-column Dropdown list? See attached image for more clarity

Hi,

This post is more of a question than an article.

I want to implement a multi-column drop down box where in I should be able to filter the results appearing below as I type along with auto-complete feature. A sample implementation of what I want can be seen in the below image.

Multi-column-DropDown-Combo-Box

I want to implement a similar Drop down list using C#. Can someone please help me out with it? I have referred to THIS LINK which pretty much shows exactly what I’m expecting but it is being done in LightSwitch. I’m not really aware of LightSwitch but still I’m trying. Meanwhile, if someone can guide me in creating similar functionality in C#, ASP.NET, it would be great! 🙂

Thanks a lot!!

‘yield’ Keyword in C#

Hi,

This post is mainly about the ‘yield’ keyword provided in C#. I never really got a chance to use this keyword until now. So thought I would just blog about it. This blog is not of my own writing; I would say it is rather a re-blogging of a discussion about the keyword in this link.

yield‘ keyword is used in an Iterator block to provide a value to the enumerator object or to signal the end of an iteration. The syntax of yield statement is as follows:

yield return <expression>;
yield break;

The following example clearly illustrates the proper usage of the keyword. The example shows two ways of returning an IEnumerable of “Product” entities.

Version-1: Using yield return

public static IEnumerable<Product> GetAllProducts()
{
    using (AdventureWorksEntities db = new AdventureWorksEntities())
    {
        var products = from product in db.Product
                       select product;

        foreach (Product product in products)
        {
            yield return product;
        }
    }
}

Version-2: returning the list

public static IEnumerable<Product> GetAllProducts()
{
    using (AdventureWorksEntities db = new AdventureWorksEntities())
    {
        var products = from product in db.Product
                       select product;

        return products.ToList<Product>();
    }
}

The main usage of the yield keyword can be realized when we have to calculate the next value in the list or the next item in the list. In the second version above, when the return keyword is reached, the entire list is ready whereas in version-1, the entire list is not ready when the yield return statement is reached. Instead, for each occurrence of the yield return statement, the next item in the to-be-returned list is calculated.

One really good use of this type of functionality is that this helps spread the computational cost over a larger time frame. For example, if the list is hooked up to a GUI and the user never goes to the last page, you never calculate the final items in the list.

Another case where yield-return is preferable is if the IEnumerable represents an infinite set. Consider the list of Prime Numbers, or an infinite list of random numbers. You can never return the full IEnumerable at once, so you use yield-return to return the list incrementally.

In the above two versions, the one that is preferable is the version-2 as the product list is finite. So we can just calculate the complete list before itself.

And above all, thanks to the author of that post that  helped me clearly understand the usage of the keyword.

Hope this helps!! 🙂