Can I return a Task directly with HttpResponseMessage, such no async declaration is needed - asynchronous

I have the following WebAPI action and is wondering if returning Task<bool> and return _store.ContainerExistsAsync(container) directly is better;
I ask because, if I understand async/await correctly, the compiler creates a statemachine at the await to return to the same state. Returning the task directly without having to await it in the action, would that be theoretical faster?
public async Task<HttpResponseMessage> GetContainer(string container)
{
if (container.Length < 3 ||
container.Length > 63 ||
!Regex.IsMatch(container, #"^[a-z0-9]+(-[a-z0-9]+)*$"))
return Request.CreateResponse(HttpStatusCode.BadRequest, new { errors = new string[1] { "Container Name is not alowed." } })
return Request.CreateResponse<bool>(HttpStatusCode.OK, await _store.ContainerExistsAsync(container));
}

Yes, if you can implement an asynchronous method without async and await, then go ahead; async/await will add overhead.
This is commonly seen when the last line of a method has the only await and looks like return await ...;
In your particular example, I'm not 100% sure whether this would work since the method is doing something after the await.
It's easy enough to make it return the Task<bool> from ContainerExistsAsync directly, but the error handling would also need to change. If throwing a HttpResponseException works well enough, then yes, you would be able to implement an asynchronous method without using async.

Related

Difference between returning a Task and using async/await [duplicate]

Is there any scenario where writing method like this:
public async Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return await DoAnotherThingAsync();
}
instead of this:
public Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return DoAnotherThingAsync();
}
would make sense?
Why use return await construct when you can directly return Task<T> from the inner DoAnotherThingAsync() invocation?
I see code with return await in so many places, I think I might have missed something. But as far as I understand, not using async/await keywords in this case and directly returning the Task would be functionally equivalent. Why add additional overhead of additional await layer?
There is one sneaky case when return in normal method and return await in async method behave differently: when combined with using (or, more generally, any return await in a try block).
Consider these two versions of a method:
Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return foo.DoAnotherThingAsync();
}
}
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
The first method will Dispose() the Foo object as soon as the DoAnotherThingAsync() method returns, which is likely long before it actually completes. This means the first version is probably buggy (because Foo is disposed too soon), while the second version will work fine.
If you don't need async (i.e., you can return the Task directly), then don't use async.
There are some situations where return await is useful, like if you have two asynchronous operations to do:
var intermediate = await FirstAsync();
return await SecondAwait(intermediate);
For more on async performance, see Stephen Toub's MSDN article and video on the topic.
Update: I've written a blog post that goes into much more detail.
The only reason you'd want to do it is if there is some other await in the earlier code, or if you're in some way manipulating the result before returning it. Another way in which that might be happening is through a try/catch that changes how exceptions are handled. If you aren't doing any of that then you're right, there's no reason to add the overhead of making the method async.
Another case you may need to await the result is this one:
async Task<IFoo> GetIFooAsync()
{
return await GetFooAsync();
}
async Task<Foo> GetFooAsync()
{
var foo = await CreateFooAsync();
await foo.InitializeAsync();
return foo;
}
In this case, GetIFooAsync() must await the result of GetFooAsync because the type of T is different between the two methods and Task<Foo> is not directly assignable to Task<IFoo>. But if you await the result, it just becomes Foo which is directly assignable to IFoo. Then the async method just repackages the result inside Task<IFoo> and away you go.
If you won't use return await you could ruin your stack trace while debugging or when it's printed in the logs on exceptions.
When you return the task, the method fulfilled its purpose and it's out of the call stack.
When you use return await you're leaving it in the call stack.
For example:
Call stack when using await:
A awaiting the task from B => B awaiting the task from C
Call stack when not using await:
A awaiting the task from C, which B has returned.
Making the otherwise simple "thunk" method async creates an async state machine in memory whereas the non-async one doesn't. While that can often point folks at using the non-async version because it's more efficient (which is true) it also means that in the event of a hang, you have no evidence that that method is involved in the "return/continuation stack" which sometimes makes it more difficult to understand the hang.
So yes, when perf isn't critical (and it usually isn't) I'll throw async on all these thunk methods so that I have the async state machine to help me diagnose hangs later, and also to help ensure that if those thunk methods ever evolve over time, they'll be sure to return faulted tasks instead of throw.
This also confuses me and I feel that the previous answers overlooked your actual question:
Why use return await construct when you can directly return Task from the inner DoAnotherThingAsync() invocation?
Well sometimes you actually want a Task<SomeType>, but most time you actually want an instance of SomeType, that is, the result from the task.
From your code:
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
A person unfamiliar with the syntax (me, for example) might think that this method should return a Task<SomeResult>, but since it is marked with async, it means that its actual return type is SomeResult.
If you just use return foo.DoAnotherThingAsync(), you'd be returning a Task, which wouldn't compile. The correct way is to return the result of the task, so the return await.
Another reason for why you may want to return await: The await syntax lets you avoid hitting a mismatch between Task<T> and ValueTask<T> types. For example, the code below works even though SubTask method returns Task<T> but its caller returns ValueTask<T>.
async Task<T> SubTask()
{
...
}
async ValueTask<T> DoSomething()
{
await UnimportantTask();
return await SubTask();
}
If you skip await on the DoSomething() line, you'll get a compiler error CS0029:
Cannot implicitly convert type 'System.Threading.Tasks.Task<BlaBla>' to 'System.Threading.Tasks.ValueTask<BlaBla>'.
You'll get CS0030 too, if you try to explicitly typecast it.
This is .NET Framework, by the way. I can totally foresee a comment saying "that's fixed in .NET hypothetical_version", I haven't tested it. :)
Another problem with non-await method is sometimes you cannot implicitly cast the return type, especially with Task<IEnumerable<T>>:
async Task<List<string>> GetListAsync(string foo) => new();
// This method works
async Task<IEnumerable<string>> GetMyList() => await GetListAsync("myFoo");
// This won't work
Task<IEnumerable<string>> GetMyListNoAsync() => GetListAsync("myFoo");
The error:
Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.List>' to 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable>'

async is snowballing to callers, can't make constructor async

I have a function loadData that loads some text from a file:
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/data/entities.json');
}
The loadString method is from Flutter SDK, and is asynchronous.
The loadAsset method is then called in another method, that must me marked as async, since loadAsset is async and I need to use await:
Future<List<Entity>> loadEntities() async {
String jsonData = await loadAsset();
return parseData(jsonData);
}
The parseData method is not async, it receives a String, parse it, and return a list of objects:
List<Entity> parseData(String jsonString) {
...
}
But since loadEntities must be marked with async, this requires that it returns a Future, but in practice, it's not a Future because since I use await, it awaits for the loadAsset method to finish, then call the parseData funcion using the result.
This easily turns into a snowball of async call, because every method that uses loadEntities must be marked as async too.
Also, I can't use loadEntities in a class constructor, because the constructor should be marked as async, which is not allowed in Dart.
Am I using the async/await pattern in Dart wrong? How could I use the loadEntities method in a class constructor?
No, async is contagious and there is no way to go back from async to sync execution.
async/await is only syntactic sugar for methodThatReturnsFuture().then(...)
Marking a method with async is only to allow you to use await inside its body. Without async you would still need to return a Future for calling code to only execute after the result of loadAsset() becomes available.
You can use the Future returned from the async call directly. This would look something like this:
class HasAsync {
HasAsync() {
asyncFunction().then((val) {
print(val);
});
}
Future<int> asyncFunction() async {
int val = await otherFunction();
return val;
}
}
You just can't use await within the non-async function.
As you've tagged this with 'flutter', I'm going to guess this is within a flutter app. If that's the case look at the docs for FutureBuilder - it might help with what you're trying to do.
I know I may be too late for you to make any use of this answer but I am writing it anyways hoping someone will find it useful. So here is my two cents.
I had the same thought process as you did when I first tried to figure out what is asynchronous programming and how it can be used.
Since the question is regarding Flutter, I will use dart to explain this.
First, let's dive in to the the basic actually the purpose of using async await in asynchronous programming.
According to the flutter documentation, the purpose of async and await keywords is to declaratively mark a function as asynchronous and use it's results.
To define an async function, add async before the function body
The await keyword works only in async functions.
Therefore, whenever you try to get an output from a function marked as asynchronous it will have no option but to return a Future. Look at the following example for more clarification.
Firstly, you have a function which will do some calculations
Secondly, you have a simple function which gets data from an API by doing a simple http get request.
finally another function which will process some data and print some values.
void processInfo(){
calculateStuff();
Future<Map> decodedData = getDataFromInternet();
getDataProcessed(decodedData);
}
so in synchronous programming this would mean that all three functions will execute one after another. But let's say the second function getDataFromInternet() is called asynchronously. A simple implementation would be like below.
Future<Map> getDataFromInternet() async {
http.Response response = await http.get(this._apiPath);
Map decodedData;
if (response.statusCode != 200)
print("invalid response. cannot proceed!");
else {
decodedData = jsonDecode(response.body);
}
return decodedData;
}
So the above function is required to return a future. The question is why?
It's simple. In this case, it's because since we want to return something and by the time the return statement is executed and the data from the 'get request' may or may not be available at that moment.
Thus, the function returns a Future type result which and either be in complete state or incomplete state.
So how can we process this result? As a matter of fact this can be done in 3 ways.
1. Method One - Handle it as a promise
So once the getDataFromInternet() function returns a Future result in this example, you need the process that future result like how you'd handle a promise in javascript. Refer the code sample below.
void getDataProcessed(Future<Map> data) {
print('getting data from future map');
data.then((d) {
print(d);
});
}
2. Method Two - mark the parent function asynchronous (contagious way)
void processInfo() async{
calculateStuff();
//now you can simply await that result and process the result rather
//than handling a Future<Map> result in this case.
//Note: it is not required to use future variable because we are awaiting
//for result
Map decodedData = await getDataFromInternet();
getDataProcessed(decodedData);
}
so in this case the getDataProcessed() function will look something like this.
void getDataProcessed(Map data) {
//this will simply print the data object which is complete result which is by
//no way is a promise object
print(data);
}
3. Method Three - Use the results from the asynchronous method in a synchronous function (non-contagious way)
In this case the processInfo() function will change slightly, i.e. the getDataProcessed() will no longer be invoked in this method and will look something like this.
void processInfo(){
calculateStuff();
getDataFromInternet();
}
Instead of invoking getDataProcessed() in processInfo() function, we can use the result from getDataFromInternet() function to invoke the getDataProcessed() function.this mean we won't have to mark processInfo() as async and we can process getDataProcessed() method after we finish executing getDataFromInternet() method. The following code sample demonstrates how to do it.
void getDataFromInternet() async {
http.Response response = await http.get(this._apiPath);
Map decodedData;
if (response.statusCode != 200)
print("invalid response. cannot proceed!");
else {
decodedData = jsonDecode(response.body);
}
//in this case, since we are awaiting for get results response and the
//function is not expected to return anything the data type passed into
//getDataProcessed() function now will be of type Map rather than being type
//Future<Map> . Thus allowing it to be a synchronous function and without
//having to handle the future objects.
getDataProcessed(decodedData);
}
void getDataProcessed(Map data) {
//this will simply print the data object which is complete result which is by
//no way is a promise object
print(data);
}
So revising back this long answer,
async/await is just the declarative way to mark asynchronous functions
when an asynchronous function is called it can be handled in 3 ways.
get the return Future and handle it like a promise with the use of 'then()' function so no need to mark the parent
function async
mark the parent function async and handle the returned object with await to force the function to wait for the result.
call the desired function with the output of the async function at the end of the async function. This will allow the main
function to continue non-dependent functions while waiting for the
results of the async function and one the async function get the
results it can go in to the other function at the end and execute it
with the data received.
then and await are different. await will stop the program there until the Future task is finished. However then will not block the program. The block within then will be executed when the Future task is finished afterwards.
If you want your program to wait for the Future task, then use await. If you want your program to continue running and the Future task do it things "in the background", then use then.
As to your problem, I suggest redesign it. Do the loading assets and other async things that are needed for the constructor elsewhere. After these tasks are completed, then call the constructor.

Web API Service - How to use "HttpContext.Current" inside async task

I'm using a "Post" async method of webApi rest service:
public async Task<object> Post([FromBody]string data)
{
object response = ExecuteServerLogics(data);
return response;
}
This above code worked good but in some of the client's calls, we experienced performance issues.
After reading some articles here, i've noticed that our webApi rest service,
is not really working asynchronously with its incoming web requests,
because we forgot to use async/await pattern :
public async Task<object> Post([FromBody]string data)
{
object response = await Task<object>.Run( () =>
{
return ExecuteServerLogics(data);
});
return response;
}
After this fix we noticed the performance got better,
but we found another critic problem:
when accessing HttpContext.Current - it returns Null reference:
public async Task<object> Post([FromBody]string data)
{
object response = await Task<object>.Run( () =>
{
var currentContext = HttpContext.Current; // Returns Null!
return ExecuteServerLogics(data);
});
return response;
}
We tried to found a solution for it, and in most posts we found that we should pass the
worker thread's HttpContext reference into the inner Task that executes the server logics.
The problem with this solution is that the server's logics methods, use many static classes that use
"HttpContext.Current" such as -
Loggers calls.
static security classes that retrieves the user.identity
static security classes that retrives the incoming request's session data, etc.
Therefore, passing the "HttpContext.Current" reference of the worker thread won't solve it.
When we tried the next solution:
public async Task<object> Post([FromBody]string data)
{
// Save worker context:
var currentContext = HttpContext.Current;
object response = await Task<object>.Run( () =>
{
// Set the context of the current task :
HttpContext.Current = currentContext ; // Causes the calls not to work asynchronously for some reason!
// Executes logics for current request:
return ExecuteServerLogics(data);
});
return response;
}
for some reason, we noticed the performance got worse again, like it had returned working synchronously again.
Our problems are:
1. Why in the last example, setting the "HttpContext.Current" inside the await task,
causes the requests to return the same bad performance results which similar to the synchronous results?
2. Is there another way we can use "HttpContext.Current" inside the inner task that call - "ExecuteServerLogics",
and in all the static classes which also call "HttpContext.Current"?
am I doing the entire design wrong somehow?
Thanks!
From the beginning:
public async Task<object> Post([FromBody]string data)
{
object response = ExecuteServerLogics(data);
return response;
}
Don't ignore compiler warnings; the compiler will generate a warning for this method that specifically states it will run synchronously.
Moving on:
in some of the client's calls, we experienced performance issues.
Asynchronous code on the server will not be faster for a single call in isolation. It only helps you scale your server.
In particular, Task.Run will negate all the performance benefits of async and then degrade performance a bit beyond that. I believe the improvement in performance that you measured was coincidental.
in most posts we found that we should pass the worker thread's HttpContext reference into the inner Task that executes the server logics.
Those posts are wrong. IMHO. You end up using the HttpContext object from a background thread, when that object is specifically designed to be only accessed from a request thread.
am I doing the entire design wrong somehow?
I do recommend you take a step back and think about the big picture. When a request comes in, it has a certain amount of work to do. Whether that work is done synchronously or asynchronously is immaterial to the client; both approaches will take about the same amount of time.
If you need to return early to the client, then you'll need a completely different architecture. The usual approach is to queue the work to a reliable queue (e.g., Azure queue), have a separate backend (e.g., Azure WebRole), and proactively notify the client when the work is completed (e.g., SignalR).
That's not to say that async is useless, though. If ExecuteServerLogics is an I/O bound method, then it should be made asynchronous rather than blocking, and then you can use asynchronous methods as such:
public async Task<object> Post([FromBody]string data)
{
object response = await ExecuteServerLogicsAsync(data);
return response;
}
This will enable your server to be more responsive and scalable overall (i.e., not get overwhelmed by many requests).
If your task is inside your ApiController-derived class, you can use:
var ctx = this.Request.Properties["MS_HttpContext"] as System.Web.HttpContextWrapper;
This will give you an HttpContext wrapper with all the usual properties.
Amir I think you're looking for something like this below. I've been dealing with the same issue, trying to optimize a series of calls. It needs to be async all the way through, which means your ExecuteServerLogics() would need to be async, and you'd have to mark the containing lamda as async as well.
I believe following that pattern you can probably eliminate most of your performance issues. Nice passing the context through like that.
public async Task<object> Post([FromBody]string data)
{
// Save worker context:
var currentContext = HttpContext.Current;
object response = await Task<object>.Run(async () =>
{
// Set the context of the current task :
HttpContext.Current = currentContext ;
// Executes logics for current request:
return await ExecuteServerLogics(data);
});
return response;
}

Using "async" (even if it should complete) as part of a MVC route deadlocks the route; how can this be avoided?

Consider the following (based on the default MVC template), which is a simplified version of some "stuff" that happens in the background - it completes fine, and shows the expected result, 20:
public ActionResult Index()
{
var task = SlowDouble(10);
string result;
if (task.Wait(2000))
{
result = task.Result.ToString();
}
else
{
result = "timeout";
}
ViewBag.Message = result;
return View();
}
internal static Task<long> SlowDouble(long val)
{
TaskCompletionSource<long> result = new TaskCompletionSource<long>();
ThreadPool.QueueUserWorkItem(delegate
{
Thread.Sleep(50);
result.SetResult(val * 2);
});
return result.Task;
}
However, now if we add some async into the mix:
public static async Task<long> IndirectSlowDouble(long val)
{
long result = await SlowDouble(val);
return result;
}
and change the first line in the route to:
var task = IndirectSlowDouble(10);
then it does not work; it times out instead. If we add breakpoints, the return result; in the async method only happens after the route has already completed - basically, it looks like the system is unwilling to use any thread to resume the async operation until after the request has finished. Worse: if we had used .Wait() (or accessed .Result), then it will totally deadlock.
So: what is with that? The obvious workaround is "don't involve async", but that is not easy when consuming libraries etc. Ultimately, there is no functional difference between SlowDouble and IndirectSlowDouble (although there is obvious a structural difference).
Note: the exact same thing in a console / winform / etc will work fine.
It's to do with the way the synchronization context is implemented in ASP.NET (Pre .NET 4.5). There's tons of questions about this behavior:
Task.WaitAll hanging with multiple awaitable tasks in ASP.NET
Asp.net SynchronizationContext locks HttpApplication for async continuations?
In ASP.NET 4.5, there's a new implementation of the sync context that's described in this article.
http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime-targetframework.aspx
When you use .Result there is always a possibility of deadlock because .Result is blocking by nature. The way to avoid deadlocks is to not block on Tasks (you should use async and await all the way down). The subject is in details described here:
Don't Block on Async Code
One fix is to add ConfigureAwait:
public static async Task<long> IndirectSlowDouble(long val)
{
long result = await SlowDouble(val).ConfigureAwait(false);
return result;
}
Another fix is to use async/await throughout:
public async Task<ActionResult> Index()
{
var task = IndirectSlowDouble(10);
long result = await task;
ViewBag.Message = result.ToString();
return View();
}

Preventing a deadlock when calling an async method without using await

I need to call a method returning a Task from within
public override void OnActionExecuting(ActionExecutingContext filterContext)
It wont let me make this method async it throws the following
An asynchronous module or handler completed while an asynchronous
operation was still pending.
and when calling
entityStorage.GetCurrentUser().Result
I get a deadlock. How can I avoid this?
I have been playing around with it coming up with stuff like
entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult();
But this isn't working. How can I do it? My solution will need to work with ASP.NET 4 and the Async Targetting Pack, I can't use ASP.NET 4.5 as am deploying to Azure.
The cause of the deadlock is explained here. In short, don't block on async code. You should use ConfigureAwait(false) in your library async code and await the results (not use Result or Wait).
Update: Please vote here for the MVC team to add support for async action filters.
Since await is just syntax sugar for the compiler rewriting a continuation for you, the most 'direct' path would be to take whatever code was going to follow your await and make it a ContinueWith call.
So, something like:
entityStorage.GetCurrentUser().ContinueWith(t =>
{
// do your other stuff here
});
If you MUST convert asynch to synch.
public User GetCurrentUserSynch()
{
return Task.Run(() =>
{
var asyncResult = entityStorage.GetCurrentUser();
while (!asyncResult.IsCompleted)
{
Application.Current.TryFindResource(new object()); // This is for WPF but you can do some other nonsense action of your choosing
}
return asyncResult.Result;
}).Result;
}
Otherwise use #Stephen's answer.

Resources