HttpClient single instance or multiple

Recently, we were working on a project that needed numerous HTTP requests to be made. Initial implementation had a new HttpClient object being created for every request being made. It looked to have some performance cost attached to it that led us to evaluate the effect of using single vs multiple instances of HttpClient.

Problem Statement:

Whats the best way to use HttpClient for multiple requests and the performance cost associated with it?

Assessment:

Went through the Microsoft documentation, which seemed updated based on last when I read few years back. Found a fineprint for myself that states:

HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors.

This was a straight give away that we should use a single instance HttpClient – irrespective of a usecase, one would want to keep distance from SocketException errors (though probability of it would be high for heavy usage of HTTP requests).

Now, the query was how to have single HttpClient for multiple requests but with different request payload for the calls? Also, does this has any impact on performance of the calls and if so, how much?

Resolution:

I started with looking into performance aspect for the two options. Created a test application that helped evaluate the time taken for various number of requests. Tried with www.google.com but seems they have some kind of check at 1000 requests so went ahead with www.bing.com that looked uniform till 5000 requests that I tried with.

for (var i = 0; i < noOfConnections; i++)
{
    using (var httpClient = new HttpClient())
    {
        var result = httpClient.GetAsync(new Uri("http://www.bing.com/")).Result;
    }
}
//having private static readonly HttpClient _httpClient = new HttpClient();
for (var i = 0; i < noOfConnections; i++)
{
    var result = _httpClient.GetAsync(new Uri("http://www.bing.com/")).Result;
}

With the above, I got the following numbers on an average post few runs:

No of RequestsMultiple Instance (s)Single Instance (s)%age Diff
1002016.6716.65
5001038814.56
100021617419.44
200043035118.37
5000103290612.21

It looked like the difference peaked around 1000 requests and overall there was an improvement with single instance.

Now, given we had a usecase where multiple HTTP requests has to be made simultaneously but with different payloads, looked at how to achieve it with single instance. Keeping multiple types of requests, unit testing, high load – One possible way looked like below that worked out well for us:

// Single instance of HttpClientManager was setup
public class HttpClientManager : IHttpClientManager
{
    ...
    public HttpClientManager(HttpMessageHandler messageHandler)
    {
        _httpClient = new HttpClient(messageHandler);
    }
    private HttpRequestMessage SetupRequest(IRequestPayload requestPayload)
    {
        var request = new HttpRequestMessage
        {
            RequestUri = new Uri(requestPayload.Url)
        };
        switch (requestPayload.RequestType)
        {
            case RequestType.POST_ASYNC:
                request.Method = HttpMethod.Post;
                request.Content = GetHttpContent(requestPayload.ContentJson);
                break;
            case RequestType.PUT_ASYNC:
                request.Method = HttpMethod.Put;
                request.Content = GetHttpContent(requestPayload.ContentJson);
                break;
            case RequestType.DELETE_ASYNC:
                request.Method = HttpMethod.Delete;
                break;
            case RequestType.GET_ASYNC:
                request.Method = HttpMethod.Get;
                break;
            default:
                request.Method = HttpMethod.Get;
                break;
        }
        ...
    }
    public HttpResponseMessage ExecuteRequest(IRequestPayload requestPayload)
    {
        HttpRequestMessage httpRequestMessage = SetupRequest(requestPayload);
        HttpResponseMessage httpResponseMessage = _httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead).Result;
        return httpResponseMessage;
    }
    private HttpContent GetHttpContent(string contentJson)
    {
        return new StringContent(contentJson, ENCODING, MEDIATYPE_JSON);
    }
}

Since there are numerous articles on the web explaining details of the entire HttpClient workflow and inner details, I will not cover that here but a quick explanation on couple of key info. In the code above:

HttpRequestMessage is used to setup HttpClient object based on our need. We make use of the fact that HttpRequestMessage can be used only once. After the request is sent, it is disposed immediately to ensure that any associated Content object is disposed.

Making use of HttpClient underlying implementation, have used HttpMessageHandler more from the unit test point of view.

Conclusion:

One should use a single instance of HttpClient at application level to avoid create/destroy of it multiple times. Further, results suggest this also has better performance with more than 12% improvement based on the load.

For multiple requests of different payloads, having a single instance HttpClient but a new HttpRequestMessage for every request looked a good approach to use.

P.S.: For .NET Core, Microsoft added a new interface around the same discussion to have better handle at HttpClient instance: https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

Entire code for lookup can be downloaded from here.

Microsoft Build Conference 2016: Keynote announcements

Wanted to share across the Microsoft’s Build conference Keynote announcements that was done on March 30 2016.

Windows 10: Usage
Out for 8 months

  • 810M users world-wide
  • 270M users in US
    • 5B visitis to the Windows Store
    • 60% growth in the “last few months alone”
    • Coming soon Universal Windows Platform Apps: includes new Facebook app + audience network

Windows 10: Update
Anniversary update of Windows 10 coming this summer (FREE)

  • Update For – New Pcs, 5-year old Pcs or a Brand New Macs
  • Insider version available today along with Update of Visual Studio 2
  • Windows Hello, Ink, Gaming, Hololens, and Cortanna updates

Desktop App Converter:
Takes a modern Win32/.Net app/Game installer and runs it though Centennial tool

  • Sage example – run it through centennial and submit to the Windows 10 app store.
  • Visual studio – Win32 code with no modifications
  • Added in Live Tile code
  • Game examples with Age of Empires 2 HD

HoloLens:

  • Starts to ship to developers and enterprise partners today (exclusive to Windows 10)
  • Code example on github are available today on the Windows Store (“Galaxy Explorer”)

“Bash” shell:
Coming to Windows (native Ubuntu windows)

  • Power of command-line tools
  • example using JavaScript, ssh, Ruby and emacs

Windows Ecosystem:

  • Cortanna as a “boundary-less” offering across all devices and user actions/history

To me, in order to have Win10 capture more market, one of the most interesting support to look forward would be: Support for Win32 Desktop apps to the Windows 10 store (coming in June)

Microsoft IE Support

Microsoft shared the following information with us in order to be better prepared. As per Microsoft Support Lifecycle policy, beginning January 12, 2016, only the most current version of Internet Explorer available for a supported operating system will receive technical support and security updates, as shown below:

Windows Desktop Operating SystemsInternet Explorer Version
Windows Vista SP2Internet Explorer 9
Windows 7 SP1Internet Explorer 11
Windows 8.1 UpdateInternet Explorer 11
Windows Server Operating SystemsInternet Explorer Version
Windows Server 2008 SP2Internet Explorer 9
Windows Server 2008 IA64 (Itanium)Internet Explorer 9
Windows Server 2008 R2 SP1Internet Explorer 11
Windows Server 2008 R2 IA64 (Itanium)Internet Explorer 11
Windows Server 2012Internet Explorer 10
Windows Server 2012 R2Internet Explorer 11
Windows Embedded Operating SystemsInternet Explorer Version
Windows Embedded for Point of Service (WEPOS)Internet Explorer 7
Windows Embedded Standard 2009 (WES09)Internet Explorer 8
Windows Embedded POSReady 2009Internet Explorer 8
Windows Embedded Standard 7Internet Explorer 11
Windows Embedded POSReady 7Internet Explorer 11
Windows Thin PCInternet Explorer 8
Windows Embedded 8 StandardInternet Explorer 10
Windows 8.1 Industry UpdateInternet Explorer 11

Microsoft Support Lifecycle policy provides consistent and predictable guidelines for product support availability when a product releases and throughout that product’s life. By understanding the product support available, customers are better able to maximize the management of their IT investments and strategically plan for a successful IT future.

Microsoft


They recommend to customers running on an older version of Internet Explorer to migrate to one of the above supported operating systems and browser combinations by January 12, 2016.

For more details, one can refer: https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer

HTML5: Tips !!!

Long time, since I have blogged. Specifically, this particular post – had all the details and wanted to post more than a year back. I guess, better late than never!
Here are few of the HTML5 tips that might help while using it’s various features:

HTML5 WebSocket Protocol is present only from IIS 8.0

HTML5 Web Socket provides a two-way communication over one TCP connection (socket). IIS 8.0 (ships with Windows 8) is capable of accepting Web Socket communications. In order to use the new protocol, one has to enable it in IIS 8.0, using option “Turn Windows features on or off” present in the control panel. It should look like below:
WebSocketIIS8
A quick detail on how WebSocket works can be looked here in my article: http://www.codeproject.com/Articles/546960/HTML-Quick-Start-Web-Application#websocket
 

One can support new HTML5 elements in older browsers using HTML5 shiv

Older browsers that are still widely used by end users (namely IE6/7/8) do not have support for the new elements in HTML5. One great way to enable HTML5 element support in IE6/7/8 is to have the http://code.google.com/p/html5shiv/
As noted on the linked Google page, “shiv” and “shim” are interchangeable terms in this context.
In case interested, I came across a good sample example and details out here: http://www.sitepoint.com/html5-older-browsers-and-the-shiv/
 

Elements in HTML5 can easily be made draggable

The specifications defines an event-based mechanism – a JavaScript API and additional markup for declaring it. Any type of element can be marked draggable on a page. It’s a known fact that having a native browser support for a particular feature is best as they would be faster and provide a more responsive application.
A quick detail about the feature can be read here: http://www.codeproject.com/Articles/546960/HTML-Quick-Start-Web-Application#dragdrop
 

‘Type’ attribute for script and link are no more required in HTML5

Type attribute is optional and one does not need to provide it for script and link tag in HTML5.
Earlier, one used to give:

<link rel="stylesheet" href="somepath/somestylesheet.css" type="text/css" />
<script type="text/javascript" src="somepath/somescript.js" />

Now, in HTML5, same references can be provided as:

<link rel="stylesheet" href="somepath/somestylesheet.css" />
<script src="somepath/somescript.js" />

This makes things simpler as the file extension and the tag were enough to interpret the type.
 

async attribute has been added to <script> tag in HTML5

HTML5 has added a new attribute for <script> tag, which is async. With this attribute, the external script will be executed asynchronously as soon as it is available. It has no effect on inline scripts.
Inline scripts and scripts without async or defer attributes are fetched and executed immediately, before the browser continues to parse the page.
 

In HMTL5, all unknown element in all browsers are displayed inline by default

The three most commonly used values are none, block, and inline. All elements have an initial or default state for their display value.For all HTML5 elements, by default they have a computed display value of inline.
 

In HTML5, page and worker do not share the same instance

In HTML5, page and worker do not share the same instance – a duplicate is created on each pass. Data passed between the main page and workers are copied. Objects are serialized as they’re handed to the worker, and subsequently, deserialized on the other end. I read that most browsers implement this feature as structured cloning. (The structured clone algorithm is a new algorithm defined by the HTML5 specification for serializing complex JavaScript objects.)
A quick detail about the feature can be read here: http://www.codeproject.com/Articles/546960/HTML-Quick-Start-Web-Application#webworkers
 

In HMTL5 Offline, relative URLs listed in a manifest are resolved relative to the manifest file

Yes, the urls in the manifest are relative to manifest’s own url. It is not to be confused that they are relative to root. Though it might happen that the urls relative to root work good because the manifest file might be located in the application root.
A quick detail about the feature can be read here: http://www.codeproject.com/Articles/546960/HTML-Quick-Start-Web-Application#offlineapp

Microsoft Products Retirement

Earlier, I was not sure if I can share the information outside, but got a confirmation today that I can.
Microsoft shared the following information with us in order to be better prepared for the upcoming year.
These are the Microsoft products that are going to retire this year and be End Of Life, meaning – End of support.

Product End Of Life Date
SQL Server 2000 4/9/2013
Commerce Server 2002 7/9/2013
BizTalk Server 2004 7/8/2014
Project Server 2003 4/8/2014
Live Communication Server 2003 1/14/2014
Office 2003 4/8/2014
Windows XP 4/8/2014
.NET Framework 1.1 10/8/2013
Visual Studio .NET 2003 10/8/2013

It is suggested by Microsoft that we migrate to newer version if we are using any one of these products.
So please have a look at what version you are working on currently and take necessary action if needed.

Lunch Time – An MVP Community Initiative

Lunch Time is a new talk series scheduled on every alternate Wednesday during the Lunch Time, initiated and will be presented by the Microsoft Most Valuable Professionals.
Current schedule:

Date/TimeTopic
Mar 06, 2013, 12:00 PM ISTGood things about .NET 4.5
Mar 20, 2013, 12:00 PM ISTASP.NET 4.5 New Features
Apr 03, 2013, 12:00 PM ISTBuilding Site Resiliency for Exchange 2013
Apr 17, 2013, 12:00 PM ISTResponsive Apps with MVC4, WebAPI and HTML5
May 01, 2013, 12:00 PM ISTA Quick Look at HTML5
May 15, 2013, 12:00 PM ISTImplementing SQL Server AlwaysOn

Across the globe, anyone can join in and learn from technical community leaders.

I will be presenting one of the session in this series – A Quick Look at HTML5 (Event ID: 1032545489)
Sandeep Mewara LunchTime Microsoft Event 01May13
Please register! Do share your feedback post presentation.

Developer Day, Bangalore 23 February 2013

PanelDiscussion23Feb13


HelloWorldGeeks.com cordially invites to Developer Day, the quarterly dose of Microsoft Developer Technologies knowledge & learning.

They bring one focussed session on Hyper-V in Windows 8 for Developers by Vijay Raj (MVP) and a panel discussion led by Amit Bansal. Apart from Amit, panelists will include real-life developer heroes Vijay Raj, Niral Bhatt & Sandeep Mewara , all MVPs.

You have the opportunity to ask any .NET/developer related question to them. Event will be hosted in Microsoft premises in Bangalore so that your experience is fabulous.

For details and registration, please visit: Developer Day

HTML5 Quick Start Web Application

HTML5 Quick Start


I was learning HTML5 features since December. While going through it, I was playing around making a sample web application fully HTML5 enabled – kind of self learning kit that would give a basic knowledge to anyone who goes through it. Plan was to publish it as an article so that others can learn quickly and have basic features at one place. One can play around with the feature implementation straight away post download.

It took me some time to write the article as it covered good number of features. I finished working on it and have published it today on CodeProject: HTML5 Quick Start Web Application

One can have a look at it there and provide feedback.

UPDATE: Missed uploading this to Github earlier, uploaded here: https://github.com/sandeep-mewara/HTML5QuickStart

Keep learning!

HTTP 500 – Internal server error

This is another common error that troubles a lot of ASP.NET users.

Problem Statement

Generally, the questions are framed like:

I receive a HTTP 500 – Internal Server Error  exception while trying to browse my hosted web application. Exception message says “This error (HTTP 500 Internal Server Error) means that the website you are visiting had a server problem which prevented the webpage from displaying”. Please help, how to resolve it?

Assessment

Any HTTP request made to web application running on IIS (or any other web server) returns the status of the response. This HTTP status code indicates about the request success or failure. If the request was unsuccessful, it might provide the reason why so.

Out of various status code, 5xx are the codes related to Server error. They indicate that the server failed to complete the request because server encountered an error.

The 500 Internal Server Error is a very general HTTP status code. It means something has gone wrong on the website and web server is unable to specify what exactly, thus failing in fulfilling the request made by the client. This is not related to client and the fault is in the webpage/website requested that resides on server. This status code can be considered as a ‘catch-all’ server error of Web server.

More details around various HTTP status code: The HTTP status code in IIS 7.0, IIS 7.5, and IIS 8.0

Possible Resolutions

Make sure that internally web server maintains some kind of internal error logs that gives more detail of what went wrong and thus help in diagnosing the issue. Generally, it is logged into Windows Event Logs on the server. Thus, first thing while troubleshooting the error is to see Windows Event Logs on the server to find what went wrong.

Other useful thing to troubleshoot it would be to disable friendly HTTP error messages to see if the raw content can provide a direction to look more. Steps:

  • Go to menu Tools/Internet Options in your IE.
  • Click on the Advanced tab & then uncheck “Show friendly HTTP error messages” option & then click Ok.
  • Now, when on accessing the same web page, much more developer meaningful error message will be shown.

Moving on, following are most common:

Option #1:
HRESULT: 0x80070035 – The page cannot be displayed because an internal server error has occurred.
This occurs because the server that is running IIS cannot access the configured root directory of the requested location.

Resolution would be to make sure that the server that is running IIS can access the configured root directory of the requested location.

Option #2:
HRESULT: 0x800700c1 – The page cannot be displayed because an internal server error has occurred.
This occurs because a script mapping is not valid.

Resolution would be to make sure that the script mapping points to the ISAPI.dll file that can process the request.
To do this, follow these steps:

  1. Click Start, click Run, type inetmgr.exe, and then click OK.
  2. In IIS Manager, expand server name, expand Web sites, and then click the Web site that you want to modify.
  3. In Features view, double-click Handler Mappings.
  4. Make sure that the script mapping points to the correct ISAPI.dll file. (e.g: .asp files should map to the %windir%\system32\inetsrv\asp.dll file)

Option #3:
HRESULT: 0x8007007f – There is a problem with the resource you are looking for, so it cannot be displayed.
This occurs because the handler mapping for the requested resource points to a .dll file that cannot process the request.

Resolution would be to edit the handler mapping for the requested resource to point to the .dll file that can process the request.
To do this, follow these steps:

  1. Click Start, click Run, type inetmgr.exe, and then click OK.
  2. In IIS Manager, expand server name, expand Web sites, and then click the Web site that you want to modify.
  3. In Features view, double-click Handler Mappings.
  4. Right-click the script mapping that you want to edit, and then click Edit.
  5. In the Edit Script Map dialog box, type the appropriate executable file in the Executable box, and then click OK.

Option #4:
One of the other possibilities could be an issue in the way web application is hosted. Some security configuration issue or conflict due to multiple config files.

Resolution would be to make sure application is hosted correctly by published the application as website and setting up the virtual directory as needed.
More details around the known issues and their resolution:
Error message when you visit a Web site that is hosted on IIS 7.0: “HTTP Error 500.0 – Internal Server Error”
Troubleshoot an “HTTP 500 – Internal Server Error” error message on IIS 4.0 or on IIS 5.0

Conclusion

This is a server error and can only be solved by website admin who has access to files and the web-server. There can be one of/or multiple reasons to get this error. One has to track down the issue and handle accordingly.

Keep learning!

Extract node from XML having defined namespace using XPath in C#

At work, while working on one of the features, we had to get a specific node from an XML. Obvious choice was to use XPath.

Problem Statement

Ignoring specifics of XML, we directly put the XPath as expected and found that no node was found when we executed the path.
I had to look up on how to extract the deep embedded node we needed using XPath in such case.

Assessment

We observed that the elements/nodes are bound to a namespace. When we tried the direct XPath, it was attempting to address elements that are bound to the default “no namespace” namespace, and thus nothing was retrieved.
Sample XML to work with:

<?xml version="1.0"?>
<SampleXmlRoot xmlns="http://www.samplesite.com/example/SampleXmlRoot">
<SampleXmlSubRoot someValue="21" xmlns="http://www.samplesite.com/example/SampleXmlSubRoot">
<SampleXmlLevel2Node id="101" xmlns="http://www.samplesite.com/example/SampleXmlLevel2Node">
<SampleXmlNode2Extract num="2">
<A1 type="money">
<value>1234.0</value>
</A1>
<A2 type="money">
<value>123.4</value>
</A2>
<A3 type="money">
<value>12.3</value>
</A3>
</SampleXmlNode2Extract>
<SampleXmlNodeOther num="2">
<B1 type="money">
<value>234.0</value>
</B1>
<B2 type="money">
<value>23.4</value>
</B2>
</SampleXmlNodeOther>
</SampleXmlLevel2Node>
</SampleXmlSubRoot>
</SampleXmlRoot>


Based on what we observed and a quick reference, we learned that we need to register the namespace for namespace prefix mapping that will be used in defining the XPath.

Using XmlNamespaceManager object, we can provide a collection of namespace definitions that will be  used by CLR to resolve the elements used in the XML documents.

Resolution

Step 1: Define XmlNamespaceManager

// xmlDoc is XmlDocument in which full XML is loaded
XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(xmlDoc.NameTable);

// Add the namespaces used in XML to the XmlNamespaceManager
xmlnsManager.AddNamespace("sxr", "http://www.samplesite.com/example/SampleXmlRoot");
xmlnsManager.AddNamespace("sxsr", "http://www.samplesite.com/example/SampleXmlSubRoot");
xmlnsManager.AddNamespace("sxl2", "http://www.samplesite.com/example/SampleXmlLevel2Node");


Step 2: Use select method that is overloaded to use XmlNamespaceManager along with XPath
In our case, we will select the first XmlNode that matches the XPath expression where any prefixes found in the XPath expression will be resolved using the supplied XmlNamespaceManager.

String xPath = "/sxr:SampleXmlRoot/sxsr:SampleXmlSubRoot/sxl2:SampleXmlLevel2Node/SampleXmlNode2Extract";
XmlNode extractedNode = xDoc.SelectSingleNode(xPath, xmlnsManager);


XmlNode extracted OuterXml will look something like:

<SampleXmlNode2Extract num="2">
<A1 type="money">
<value>1234.0</value>
</A1>
<A2 type="money">
<value>123.4</value>
</A2>
<A3 type="money">
<value>12.3</value>
</A3>
</SampleXmlNode2Extract>

Yep, that’s the exact one we needed!

Refer:
MSDN: XmlNamespaceManager Class
MSDN: XmlNode.SelectSingleNode Method (String, XmlNamespaceManager)

Conclusion

XPath is a wonderful way to extract node(s) and we have defined methods in place to get them. We just need to know and learn about them. XmlNamespaceManager handles the namespace and helps in defining the XPath for a given XML.