8

I am using HttpClient class in my asp.net web api 2 application to post some information to a endpoint. I just want to post the information without waiting for a response. Is this the right syntax

using (var client = new HttpClient()) { client.BaseAddress = new Uri("http://localhost:9000/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // HTTP POST var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; var response = await client.PostAsJsonAsync("api/products", gizmo); } 
9
  • di you try to just get rid of the "await"? You get a warning, but maybe is what you're asking for.. Commented Mar 23, 2016 at 22:17
  • Not answer to your question. But worth sharing I think. I am using FLurl and loving it. github.com/tmenier/Flurl Commented Mar 23, 2016 at 22:23
  • Are you calling HttpClient from an ASP.NET WebApi app? Commented Mar 23, 2016 at 22:24
  • @marco.marinangeli: I want to know if I am doing it the right way? if i remove the await keyword, I get following message because this call is not awaited execution of the current method continues before the call is completed Commented Mar 23, 2016 at 22:24
  • @YuvalItzchakov:I am making call form one asp.net web api service to another asp.net web api service. Commented Mar 23, 2016 at 22:25

2 Answers 2

4

I just want to post the information without waiting for a response

Not awaiting an async method in WebAPI will result in a runtime exception, as the AspNetSynchronizationContext is aware of any triggered asynchronous operations. If it notices a controller action completes before the async operation has, it will trigger the said exception. More on that in ASP.NET Controller: An asynchronous module or handler completed while an asynchronous operation was still pending

If you want to use a fire and forget semantics, you need to queue the delegate via HostingEnvironment.QueueBackgroundWorkItem if you're using .NET 4.5.2 and above. If not, you can defer to using BackgroundTaskManager

Keep in mind this kind of design isn't really suitable for WebAPI. It doesn't scale if you're triggering this action call frequently. If this style happens often, consider using something more suitable such as a message broker.

Sign up to request clarification or add additional context in comments.

8 Comments

This isn't an answer to the question. It's possible to just POST to a server and terminate the HTTP/TCP connection. Servers can and will usually continue the request anyway. PostAsync may not be the solution here if it always reads the response.
@makhdumi That's not what I'm trying to say here. Since OP wants to execute this from ASP.NET, he'll need to be aware that the runtime is aware of tasks which are left unattended, and will cause responses to the user to return error codes instead of completing properly.
OP says "I just want to post the information without waiting for a response." The problem here is that HttpClient.PostAsync will automatically read the response stream. If one wishes to just send data and not bother reading the response, there is no actual need to have any operation, async or not, to read the request stream (ie wait for the server to respond). This is different than "fire and forget" with QueueBackgroundWorkItem. Your answer makes total sense and your point about scalability completely holds, even if just sending the response, but isn't a real answer to the question.
@makhdumi OP says "without waiting for a response", not "without reading the reponse"*. What would you suggest as an alternative?
My point is that one way or another, you're waiting for a response with PostAsync, e.g. in another thread. Like you said, this is not at all scalable since you can easily get a ton of threads waiting on a response. This can be avoided by simply not waiting on/reading, the response, in whatever thread it's being run in.
|
0

To implement the async Task in ASP.NET refer to the following sample syntax:

 protected void Page_Load(object sender, EventArgs e) { try { RegisterAsyncTask(new PageAsyncTask(LoadUrlContent)); } catch {} } protected async Task LoadUrlContent() { try { // Add your code here, for example read the content using HttpClient: string _content = await ReadTextAsync(YourUrl, 10); } catch { throw; } } 

Also, set <%@ Page ... Async="true" %> at page level.

Following sample code snippet shows the use of HttpClient (call this sample function from LoadUrlContent():

protected async Task<string> ReadTextAsync(string Url, int TimeOutSec) { try { using (HttpClient _client = new HttpClient() { Timeout = TimeSpan.FromSeconds(TimeOutSec) }) { _client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html")); using (HttpResponseMessage _responseMsg = await _client.GetAsync(Url)) { using (HttpContent content = _responseMsg.Content) { return await content.ReadAsStringAsync(); } } } } catch { throw; } } 

You can modify this code base pertinent to your particular task.

Hope this may help.

5 Comments

My application is asp.net web api. I am using HttpClient to post the information. The answer you provided does not use HttpClient class.
Please refer to the extended answer w/sample code using HttpClient. Best regards,
Thank you for quick reply. But I don't want to read the response. I just want to fire and forget. Also I am making call from one asp.net web api application to another asp.net web api application.
Then you may try Task.Run() because async/await is kind of antithetical to "fire and forget" (it's awaiting something per very definition). Still, you may use ConfigureAwait(false) to achieve the desirable result. Best regards,
ConfigureAwait can cause deadlocks on asp

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.