web api asynchronous method from .net application - c#

I have a web api 2 application and a wpf client. my question is that LINQ to Entities support multiple asynchronous method, like ToListAsync, ToArrayAsync and so on.
But in my wpf client application, there are no such things.
Can anyone give me some examples for asynchronous method in client application?

Web API calls are just straight HTTP calls. Just use the HttpClient class.
Asynchronous coding reference
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
string urlContents = await getStringTask;

Related

Web API Request is null in ExecuteAsync method of ApiController

I am trying to access the Request property in my ApiController-derived class.
For some reason, Request is null in ExecuteAsync method. I've seen the other questions, so before you ask:
I am not initializing the controller by calling the constructor, it's a regular HTTP POST API call from an external device.
I've tried the same request locally with Fiddler, the behavior is identical.
I am not unit testing.
Before hitting the ExecuteAsync method, my request passes through a delegating handler, and in the delegating handler, my request object exists (I even add some properties without any problem).
At the last line of delegating handler, I call return await base.SendAsync(request, cancellationToken); without a problem and request exists.
Right after than in API controller, HttpContext.Current.Request is not null and accessible without problem.
In API controller, RequestContext is not null and accessible without problem.
In that same line, Request is null.
Why would this occur? I'm on Web API 2.2 (and MVC 5, if relevant).
This is probably due to the fact that you're trying to access HttpContext while working with async/await.
So, you have two options:
Access the request via the ExecuteAsync method 'HttpControllerContext' parameter - controllerContext.Request.
Make sure your web.config is targeting .NET 4.5 and update appSettings with aspnet:UseTaskFriendlySynchronizationContext set to true.
You can read more here - Using HttpContext Safely After Async in ASP.NET MVC Applications.
To better understand what's going on under the hood, I'd recommend:
Understand what is SynchronizationContext - ExecutionContext vs SynchronizationContext
Understand how it is related to ASP.NET - Understanding the SynchronizationContext in ASP.NET.
In a very very high level: in a synchronous server implementations, where the entire request is processed by the same thread, the execution context is stored using TLS (thread local storage), means HttpContext is available anywhere in your code.
In an asynchronous server implementation (async/await), the request may be processed by several threads, and there's a need to pass the execution context between those threads.

System.Net.WebClient - should I use Async

I have a C# web application that makes a web service call, then renders a page for a browser. Following this advice, I chose to use System.Net.WebClient for the request because it had a succint interface and all the control I needed.
WebClient offers me async versions of all the download methods. Should I use them? I don't care if the current user waits. I need the web service result before I can render the page, and I have nothing else to be doing (for her) in the meantime. However I really do care if my server is tied up while one user's web service call completes. If this was javascript, a synchronous web request on the main thread would hold up at least the whole window. Is this the case in asp.net? For reasons outta my control, my web service request is at the bottom of a pile of 15 method calls. Dot I have to convert them all to async to see any advantage?
Generally speaking, async IO won't yield faster per-request response, but in theory it can increase throughput.
public async Task<IActionResult> YourWebApiMethod() {
// at this point thread serving this request is returned back to threadpool and
// awailable to serve other requests
var result = await Call3ptyService();
// once IO is finished we grab new thread from thread pool to finish the job
return result;
}
// thread serving this request is allocated for duration of whole operation
public IActionResult YourWebApiMethod() {
return Call3ptyService().Result;
}
You have only so-many threads in thread pool, if every single one is busy waiting for external service; your web server will stop serving requests. As for your particular problem - try it and you'll find out.

Is it important to use $timeout in angularJS while using Async and Await ing Asp.net Web API?

I just want to know if it is required to use $timeout in AngularJS as a synchronous way while I'm using Async and Await in my Serverside which is the Asp.Net Web Api.
Please explain me and let me understand if I'm going to use $timeout, Async and Await together.
Async\Await are server side operators that help you do things async in your server.
$timeout is a angularjs provider that wraps setTimeout and uses the $apply function to sync things in the angular world($apply calls digest).
If you are looking for a way to be async on the client side you should read about promises and deferred objects - This is the way to work async on the client(it doesn't matter if I'm async on server or not).

Calling async methods from a WCF service

I want to call asynchronous methods from a WCF service, something like:
[ServiceContract]
interface IService
{
[OperationContract]
int SomeMethod(int data);
}
int SomeMethod(int data)
{
var query = ... build LINQ query;
var response = await query.ToListAsync();
return response.Length;
}
I don't want to add async to the IService interface or SomeMethod method. Using asynchronous methods is an internal issue that shouldn't be reflected in the interface.
How can I do that?
CLARIFICATION:
My problem here is using await in a non-async method. I don't want the service contract to change (the client doesn't necessarily know what async is), and I don't want to split the method into BeginSomeMethod and EndSomeMethod. I want one method that uses await internally.
Whether the server is using sync or async code does not matter for the client. Client and server are separated by a well-specified wire-protocol (often SOAP). SOAP has no notion of asynchronous completion.
You can have a sync server and an async client, or vice versa. The client cannot even detect whether the server is sync or async. This is an implementation detail. The server could be a wrist watch running Linux and you still couldn't tell.
The style of IO you use is an implementation detail and does not influence the bytes that go over the network.
So pick what you like. The client can still use async IO to access the server.
I'm not sure why this is such a surprise to people. In other contexts this seems very intuitive: You can have a asynchronous TCP server and a synchronous client. I can say new WebClient().DownloadString(url) and download a string synchronously from a web-server that is implemented in an asynchronous way. I cannot even tell what server software is running.
Use Fiddler to look at what goes over the wire when you make a WCF call. There is no notion of synchronous or asynchronous calls.
Under the hood, when you invoke a service asynchronously, the WCF client library using TCP sockets in an asynchronous way. When you invoke synchronously, TCP sockets are being used with blocking calls. That's the entire difference.
WCF generated clients can be made to have asynchronous methods in addition to the synchronous methods. Select the "Generate asynchronous operations" option in the UI. Now you have both versions. Both fully functional.
Here's how you can convince yourself of this with an experiment: Write a sync server, and call it both sync and async from the same .NET client. Now write a 2nd server asynchronously (in any style you like) and use the exact same client code to call it.
Task and IAsyncResult are not serializable over SOAP anyway so it cannot possibly be the case that a Task is transmitted to the client.

Asynchronous callback from web api controller

I'm very new to Web API and I have an unusual pattern that I need to implement. In the Post method of my controller, it is to take an object which includes a CallbackURL. It will then immediately return an HTTP response to the caller. Afterwards, it will use a 3rd party, off-site API to perform some work with the object. Once that work is done, the controller is to post the results of that work to the CallbackURL.
However, I do not know how to implement this in Web API. Once I return the HTTP response, the controller's lifecycle is over, correct? If so, how do I perform the work I need to do after I return the response?
If you only need to post results to a url and not to the client that initiated the call, you could possibly do something as easy as this:
public string MyAPIMethod(object input)
{
Task.Factory.StartNew(() =>
{
//call third-party service and post result to callback url here.
});
return "Success!";
}
The api call will return right away, and the Task you created will continue the processing in a different thread.
Creating a task to finish up the request (as suggested by Jason P above) will most likely solve the problem, thread-safety provided. However that approach might hurt the performance of your Web service if calls to the 3rd party API take a significant amount of time to complete and/or you are expecting many concurrent clients. If that was the case, your problem seems to be the perfect candidate for a service pattern called "Request/Acknowledge/Callback" (also "Request/Acknowledge/Relay"). Using that pattern, your Web API method will just store each request (including the callback URL) into a queue/database and return quickly. A separate module (possibly running on more than one machine, depending on the number and complexity of the tasks) will take care of completing the tasks, and subsequently notifying completion through the callback URL (please see http://servicedesignpatterns.com/ClientServiceInteractions/RequestAcknowledge).
This is presuming you want to return the results of your 3rd-party query to the caller.
You're correct, this is outside of what's possible with WebAPI. Once you return the HTTP Response, the client also has no connection to your server.
You should look into Asp.Net SignalR, which allows a persistent connection between the client and server, working in modern browsers, and even back to IE7 (though officially unsupported), as well as supporting non-browser clients.
You can then do a couple of things, all of which require the client to connect to SignalR first.
Option 1: You can call your WebApi controller, which can return, but not before launching a task. This task can query the 3rd party api, then invoke a function on the caller via SignalR with the results that you want to provide.
Option 2: You can call a SignalR Hub action, which can talk back to your client. You can tell your client the immediate response, query the 3rd-party api, then return the results you want to provide.

Categories