Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

Making async Http Request

0.00/5 (No votes)
22 Oct 2012CPOL2 min read 13K  
This article present how to make async HTTP Request in a command line application

Introduction

In this article i'm going to introduce the HttpClient assembly and explain to you how to make async requests in a command-line application.

The difficulty is in understanding how async works and why it doesn't work in a classic command line program because of the application Context.

All this article tips about GUI is provided for Visual Studio 2012.

Context

Most C# Applications have a UI context for managing async calls. They provide automatic event based manager for handling this kind of request. But in some other type of applications this Context is not defined by default. For example in command line based program, unit testing or windows services, there is no such concept. That's why you have to define it manually.

AsyncEx

Thanks for us, we are not the first ones to have such a problem. That's why the Nito AsyncEx was created. It's an easy to install assembly that allows you to define your how Context which will handle async calls in your application.

So, first of all, you need to install the package and to reference the assembly. Installing is done using NuGet package manager to easily install it, open the package manager console (located in Tools>Library Package Manager) and type :

PM> Install-Package Nito.AsyncEx

Next you have to add a reference to the assembly :

C#
using Nito.AsyncEx;  

So now that we have the Context Package we have to manually define an entry point with the newly created Context : 

C#
using Nito.AsyncEx;
namespace TestHttpClient
{
    class Program
    {
        static void Main(string[] args)
        {
            // Launch Async Main for awaits
            try
            {
                AsyncContext.Run(() => MainAsync(args));
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
        }
        static async void MainAsync(string[] args)
        {
            // Make your async calls here
        }
    }
}  

So we have created our asynchronous context and now we can make asynchronous calls. Next we'll see how to use the System.Net.Http assembly for HTTP asynchronous calls. 

Using the code

We'll see how to make a POST request because MSDN is filled with GET examples.  But first of all, you have to add a Reference to the assembly in your project (Project>Add Reference...). Add the assembly to your used package too : using System.Net.Http; 

To be more creative, in place of getting the body response to our request, I'll show you how to get a header field.  

So, assuming we are in the MainAsync method that's how you can make a POST asynchronous request using HttpClient. 

C#
// POST arguments setted in a dictionnary
Dictionary<string, string> postArguments = new Dictionary<string, string>();
postArguments.Add("name", command);
try
{
    // Send the POST and wait for response asynchronously
    HttpResponseMessage response = await this.httpClient.PostAsync(url, new FormUrlEncodedContent(postArguments));
    // Throw an exception if it doesn't worked
    response.EnsureSuccessStatusCode();
    // Our List to stock Header values
    IEnumerable<string> Data = new List<string>();
    // If header exists, we get it in Data
    if (response.Headers.TryGetValues("Server", out Data))
    {
        foreach( var d in Data)
        {
            Console.WriteLine(d);
        }
    }
    return ret;
}
catch (Exception e)
{
    Console.Error.WriteLine( e.ToString() );
} 

And That's it.  

Points of Interest

So now on, you can almost make a curl clone all asynchronous for best performances Smile | <img src=.

A remark about windows services. It's better to use a separate thread context for asynchronous calls. To do this, you have to use the AsyncContextThread method in your service start method :

C#
// Start Point of service
protected async override void OnStart(string[] args)
{
    // Create Context Thread
    var thread = new AsyncContextThread();
    // Add the methods to the Queue
    thread.Context.Queue(() => MyFunc(args));
    // Launch Thread
    thread.Start();
    // Wait for the Queue to finish
    await thread.JoinAsync();
}  

And now you can make your asynchronous service too Big Grin | <img src=.

History 

2012.22.10 First version of this article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)