Async controller method not returning - c#

This code hangs (does not return a response) when I make a request to it:
public class MyController : ApiController
{
public async Task<IQueryable<int>> Get()
{
return await new Task<IQueryable<int>>(() => new List<int>().AsQueryable());
}
}
But this method works fine:
public IQueryable<int> Get()
{
return new List<int>().AsQueryable();
}
What fundamental knowledge am I missing??!

As the other answer noted, the reason your controller is not finishing is because the task is not started. However, using Task.Start, Task.Factory.StartNew, or Task.Run is not a good solution on ASP.NET.
The entire point of using async/await on ASP.NET is to free up a thread. However, if you await a task that is started via Start/StartNew/Run, then you're freeing up one thread by taking up another thread from the same thread pool. In this case, you not only lose all the benefits of async/await, but you actually decrease your scalability by regularly throwing off the ASP.NET thread pool heuristics.
There are two types of tasks, as I describe on my blog: Delegate Tasks (which represent some work executed on a thread) and Promise Tasks (which represent an event). You should avoid Delegate Tasks on ASP.NET, including any tasks that are "started" (Start/StartNew/Run).
Since you're returning an IQueryable<T>, I'm assuming that your actual underlying operation is a database query. If you're using EF6, then you have full support for asynchronous queries, which are properly implemented with Promise Tasks.

You're not actually starting your Task so it will wait for something that will never begin.
Instead use Task.Factory.StartNew which will create and start at the same time, or call Task#Start and await that call.
An overview of ways to start a task: http://dotnetcodr.com/2014/01/01/5-ways-to-start-a-task-in-net-c/

There is absolutely no need in async/await there, the method can look like:
public Task<IQueryable<int>> Get()
{
return Task.FromResult(new List<int>().AsQueryable());
}
If you really need it to be async, ok, you can always write something like:
public async Task<IQueryable<int>> Get()
{
return await Task.FromResult(new List<int>().AsQueryable());
}
which will introduce little overhead (a whole state machine will be generated by compiler).
Also, as others already stated, tasks returned from async methods should be hot (started)
Keep in mind, that Task.FromResult will return completed task and this case can be optimized by async/await generated code, writing Task.Run in this case is at least wierd
Read Task-based Asynchronous Pattern for more details

Related

Is having a return type of Task enough to make a method run asynchronously?

I have a simple method that does a complicated string operation and returns the result. As you can see, the return type of this method is Task<string>. Therefore, I can use Task.FromResult(result) to return the value of my string.
public Task<string> ComplexOperation()
{
string result = // Do something complex
return Task.FromResult(result);
}
Then, I can use the await keyword to call this method.
public static async Task Main(string[] args)
{
var myResult = await ComplexOperation();
}
Because I am awaiting CompelxOperation(), (waiting for the Task to return on completion) will this method run asynchronously?
Based on your comments you need to do something like this:
public Task<string> ComplexOperation()
{
return Task.Run(() => /* Do something complex */);
}
You can play with it like this:
public static async Task Main()
{
Console.WriteLine("Before" );
var myResultTask = ComplexOperation();
Console.WriteLine("After task creation");
var result = await myResultTask;
Console.WriteLine("After async await");
}
public Task<string> ComplexOperation()
{
Console.WriteLine("Creation");
return Task.Run(() =>
{
Console.WriteLine("In before work");
Thread.Sleep(500); //simulate work;
Console.WriteLine("In after work");
return "Done";
});
}
And compare the behavior with switching to your implementation when you just return Task.FromResult. Also it does not makes much sense in such test example, TBH.
Just as you flagged as async the Main method to get an asynchronous method you need to flag the method as asynchronous with the async keyword, and make the result a Task.
But in the framework Tasks are used for 2 related but different concepts, parallelization and asynchronous programming.
What you are doing is use parallelization.
So you are just running some synchronous code on a different thread.
Based on your example i think what you need is to use parallelization, which can speed up some complex calculation or work by use many threads to work in parallel.
The concept behind asynchronous code is to free the thread while you are waiting for external resources (like some data from a web service), to allow other work to be done in the meantime.
So, if you need to do complex work with local resources it's better use tasks without async logic, instead when working with remote resources you can go for asynchronous operations.
Semantically the method ComplexOperation is asynchronous because it returns an awaitable type, and in order to follow the guidelines it should be named ComplexOperationAsync.
Asynchronous methods in TAP include the Async suffix after the operation name for methods that return awaitable types, such as Task, Task<TResult>, ValueTask, and ValueTask<TResult>.
But it is not a well behaved asynchronous method. An asynchronous method is expected to return an incomplete Task immediately, allowing the caller to await the task asynchronously without been blocked. From the docs:
An asynchronous method that is based on TAP can do a small amount of work synchronously, such as validating arguments and initiating the asynchronous operation, before it returns the resulting task. Synchronous work should be kept to the minimum so the asynchronous method can return quickly.
The ComplexOperation method does exactly the opposite: it forces the calling thread to perform the complex operation, and finally it hands back a completed task. For all intents and purposes this operation is not asynchronous at all. It is 100% synchronous and 0% asynchronous, plus some overhead (to add insult to injury). So don't do this, and if there is some library that does it, don't use the library. It is simply bad practice.
Clarification: Since the term asynchronous method can mean different things in different contexts, I should clarify that the context of this answer is the perspective of the consumer, who sees the signature of the method as a contract, and builds expectations based on the visible contract and not on the invisible implementation. In this context the method ComplexOperation is asynchronous. If we switch perspective and focus on the implementation, the method ComplexOperation is not asynchronous. My statement «it is simply bad practice» refers to the practice of breaking the contract, and providing a synchronous implementation to a method with asynchronous contract. I am not criticizing the use of Task.FromResult method per se. I am criticizing it only when it follows a complex/lengthy/latent operation, that according to the method's contract should be made asynchronous.
P.S. I am thankful to #DmytroMukalov for providing (in the chat) the helpful distinction between asynchrony by contract and by implementation.

Running async functions in parallel from list of interfaces

I have a similair question to Running async methods in parallel in that I wish to run a number of functions from a list of functions in parallel.
I have noted in a number of comments online it is mentioned that if you have another await in your methods, Task.WhenAll() will not help as Async methods are not parallel.
I then went ahead and created a thread for each using function call with the below (the number of parallel functions will be small typically 1 to 5):
public interface IChannel
{
Task SendAsync(IMessage message);
}
public class SendingChannelCollection
{
protected List<IChannel> _channels = new List<IChannel>();
/* snip methods to add channels to list etc */
public async Task SendAsync(IMessage message)
{
var tasks = SendAll(message);
await Task.WhenAll(tasks.AsParallel().Select(async task => await task));
}
private IEnumerable<Task> SendAll(IMessage message)
{
foreach (var channel in _channels)
yield return channel.SendAsync(message, qos);
}
}
I would like to double check I am not doing anything horrendous with code smells or bugs as i get to grips with what I have patched together from what i have found online. Many thanks in advance.
Let's compare the behaviour of your line:
await Task.WhenAll(tasks.AsParallel().Select(async task => await task));
in contrast with:
await Task.WhenAll(tasks);
What are you delegating to PLINQ in the first case? Only the await operation, which does basically nothing - it invokes the async/await machinery to wait for one task. So you're setting up a PLINQ query that does all the heavy work of partitioning and merging the results of an operation that amounts to "do nothing until this task completes". I doubt that is what you want.
If you have another await in your methods, Task.WhenAll() will not help as Async methods are not parallel.
I couldn't find that in any of the answers to the linked questions, except for one comment under the question itself. I'd say that it's probably a misconception, stemming from the fact that async/await doesn't magically turn your code into concurrent code. But, assuming you're in an environment without a custom SynchronizationContext (so not an ASP or WPF app), continuations to async functions will be scheduled on the thread pool and possibly run in parallel. I'll delegate you to this answer to shed some light on that. That basically means that if your SendAsync looks something like this:
Task SendAsync(IMessage message)
{
// Synchronous initialization code.
await something;
// Continuation code.
}
Then:
The first part before await runs synchronously. If this part is heavyweight, you should introduce parallelism in SendAll so that the initialization code is run in parallel.
await works as usual, waiting for work to complete without using up any threads.
The continuation code will be scheduled on the thread pool, so if a few awaits finish up at the same time their continuations might be run in parallel if there's enough threads in the thread pool.
All of the above is assuming that await something actually awaits asynchronously. If there's a chance that await something completes synchronously, then the continuation code will also run synchronously.
Now there is a catch. In the question you linked one of the answers states:
Task.WhenAll() has a tendency to become unperformant with large scale/amount of tasks firing simultaneously - without moderation/throttling.
Now I don't know if that's true, since I weren't able to find any other source claiming that. I guess it's possible and in that case it might actually be beneficial to invoke PLINQ to deal with partitioning and throttling for you. However, you said you typically handle 1-5 functions, so you shouldn't worry about this.
So to summarize, parallelism is hard and the correct approach depends on how exactly your SendAsync method looks like. If it has heavyweight initialization code and that's what you want to parallelise, you should run all the calls to SendAsync in parallel. Otherwise, async/await will be implicitly using the thread pool anyway, so your call to PLINQ is redundant.

Should I use Task.Run to wait tasks in a synchronous context?

I have an ASPX page which I cannot convert to async but which uses some async methods in a synchronous context. The way it invokes them is like so:
public void MySyncMethod()
{
var myTask = Task.Run(() => _myField.DoSomethingAsync());
myTask.Wait();
//use myTask.Result
}
Is there any difference between doing that and the following as far as async/await and/or blocking goes?
public void MySyncMethod()
{
var myTask = _myField.DoSomethingAsync(); //just get the Task direct, no Task.Run
myTask.Wait();
//use myTask.Result
}
I assume a previous developer added the Task.Run for a reason. But I am having issues which accessing things in HttpContext as the work is being run on a different thread.
Is there a reason to use Task.Run here?
Is there any difference between doing that and the following as far as
async/await and/or blocking goes?
Yes the first block of code uses a thread pool thread then waits for this to return, so your using two threads not one. They both block.
I assume a previous developer added the Task.Run for a reason.
Yes, blocking (directly) on async code from an ASP.Net context is a bad idea and can cause deadlocks. So you second block of code is more efficent (in thread usage) but suffers from serious deadlock issues.
The correct solution here is to make public void MySyncMethod() async itself (public async Task MySyncMethod()). Both these solutions have drawbacks and the only real way out is to make the whole call stack async. If you can do this, do it.
If you can't call an async method from another async method then Task.Run is the way to go. See How to call asynchronous method from synchronous method in C#? for more details.
If you want HttpContext inside your thread have a read though Using HttpContext in Async Task I would definitely favour:
Make every thing async
Or the Read the values from the context then pass them
Options of those answers and keep in mind
First off, you're not creating a copy of the object, you're just
copying the reference to the object.HttpContext isn't a
struct.....etc
The internal workings of asynchronous code based on async/await is fundamentally different than tasks started by Task.Run. async/await tasks are promise based and depend on the caller cooperating with returning the execution back to the asynchronous method when appropriate. Tasks started by Task.Run however are usually started on a parallel thread taken from the thread pool and do not depend on the caller's cooperation to continue execution when appropriate.
This constellation leads to the problem that you can not treat a promise based task the same as the other tasks, since the promise based task might wait for the callers cooperation to return the execution, which might never occur since the other task is executed independently and might wait for the caller. The result is a deadlock.
The solution is a specific Task.Run overload that will create a proxy for an existing task-based method that allows proper execution of a promise based task. It is safe to call Wait on this proxy. That's why the other developer used this construct. He could have also simplified the call and avoided an anonymous method like this:
var myTask = Task.Run(_myField.DoSomethingAsync);
Task.Run is used to run code asynchronously.
Be clear that it returns Task and needs to be awaited. Here's an example:
Task myTask = Task.Run(() => DoSomething());
await myTask;

Task.Run with async lambda

public class EventService
{
public async Task InsertEventItemAsync(InsertEventItem request)
{
await SomeMethodThatUsesRestSharpToMakeAsynchronousWebApiCall(request);
}
public async Task<int> GetNumberOfEvents()
{
int result = await SomeOtherMethodThatUsesRestSharpToMakeAsynchronousWebApiCall();
return result;
}
}
public interface IFoo
{
void Bar();
int Baz();
}
public class Foo : IFoo
{
EventService _eventService;
public void Bar()
{
Task.Run(async () => await _eventService.InsertEventItemAsync());
}
public int Baz()
{
int result = Task.Run(async () => await this._eventService.GetNumberOfEvents()).Result;
return result;
}
}
That call to Task.Run in Foo.Bar() does not look right to me.
It is the approach to async code that is used everywhere in the codebase for a project I have recently started on.
My assumption is that that async lambda was written just so that the code will compile.
I am doubtful that it a good approach.
I don't have much experience with async/await but I think that this will start a new ThreadPool thread and block the current thread until the task has finished runninng on the ThreadPool thread, which will result is worse performance than if the whole lot was synchronous.
Is that code "wrong"?
It seems to me like there might be an aversion (or possibly a good reason) to going async all the way. Should I try to make the case for going either fully async or fully sync and not trying to mix them?
Thanks.
That call to Task.Run in Foo.Bar() does not look right to me.
Yes, it is Very Bad™.
Task.Run executes its delegate on a thread pool thread. Since it's an asynchronous delegate, it won't "use up" a thread pool thread any time it is "awaiting" - so you don't need to worry about that.
What you do need to worry about is what happens to the task returned from Task.Run. In particular, nothing is done with it. This is problematic because if the delegate throws an exception, that exception is placed on the task returned from Task.Run, which is... completely ignored. So you have silent failures. This is exactly as bad as writing catch { } all over the place.
Foo.Baz is using the thread pool hack (unfortunately using Result, which makes for more awkward error handling). This hack is a way of writing sync-over-async code that has no possibility of deadlocks.
It seems to me like there might be an aversion (or possibly a good reason) to going async all the way. Should I try to make the case for going either fully async or fully sync and not trying to mix them?
Yes. Ideally, the code should be async all the way (or sync all the way). There are a few situations where this is infeasible, but the vast majority of code should certainly be one or the other. Hacks like this are acceptable during a transition time when legacy code is being updated to async, but they shouldn't exist in an application long-term without good reason.

Write your own async method

I would like to know how to write your own async methods the "correct" way.
I have seen many many posts explaining the async/await pattern like this:
http://msdn.microsoft.com/en-us/library/hh191443.aspx
// Three things to note in the signature:
// - The method has an async modifier.
// - The return type is Task or Task<T>. (See "Return Types" section.)
// Here, it is Task<int> because the return statement returns an integer.
// - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();
// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;
// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}
private void DoIndependentWork()
{
resultsTextBox.Text += "Working........\r\n";
}
This works great for any .NET Method that already implements this functionality like
System.IO opertions
DataBase opertions
Network related operations (downloading, uploading...)
But what if I want to write my own method that takes quite some time to complete where there just is no Method I can use and the heavy load is in the DoIndependentWork method of the above example?
In this method I could do:
String manipulations
Calculations
Handling my own objects
Aggregating, comparing, filtering, grouping, handling stuff
List operations, adding, removing, coping
Again I have stumbled across many many posts where people just do the following (again taking the above example):
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
await DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
private Task DoIndependentWork()
{
return Task.Run(() => {
//String manipulations
//Calculations
//Handling my own objects
//Aggregating, comparing, filtering, grouping, handling stuff
//List operations, adding, removing, coping
});
}
You may notice that the changes are that DoIndependentWork now returns a Task and in the AccessTheWebAsync task the method got an await.
The heavy load operations are now capsulated inside a Task.Run(), is this all it takes?
If that's all it takes is the only thing I need to do to provide async Method for every single method in my library the following:
public class FooMagic
{
public void DoSomeMagic()
{
//Do some synchron magic...
}
public Task DoSomeMagicAsync()
{
//Do some async magic... ?!?
return Task.Run(() => { DoSomeMagic(); });
}
}
Would be nice if you could explain it to me since even a high voted question like this:
How to write simple async method? only explains it with already existing methods and just using asyn/await pattern like this comment of the mentioned question brings it to the point:
How to write simple async method?
Actual Answer
You do that using TaskCompletionSource, which has a Promise Task that doesn't execute any code and only:
"Represents the producer side of a Task unbound to a delegate, providing access to the consumer side through the Task property."
You return that task to the caller when you start the asynchronous operation and you set the result (or exception/cancellation) when you end it. Making sure the operation is really asynchronous is on you.
Here is a good example of this kind of root of all async method in Stephen Toub's AsyncManualResetEvent implementation:
class AsyncManualResetEvent
{
private volatile TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>();
public Task WaitAsync() { return _tcs.Task; }
public void Set() { _tcs.TrySetResult(true); }
public void Reset()
{
while (true)
{
var tcs = _tcs;
if (!tcs.Task.IsCompleted ||
Interlocked.CompareExchange(ref _tcs, new TaskCompletionSource<bool>(), tcs) == tcs)
return;
}
}
}
Background
There are basically two reasons to use async-await:
Improved scalability: When you have I/O intensive work (or other inherently asynchronous operations), you can call it asynchronously and so you release the calling thread and it's capable of doing other work in the mean time.
Offloading: When you have CPU intensive work, you can call it asynchronously, which moves the work off of one thread to another (mostly used for GUI threads).
So most of the .Net framework's asynchronous calls support async out of the box and for offloading you use Task.Run (as in your example). The only case where you actually need to implement async yourself is when you create a new asynchronous call (I/O or async synchronization constructs for example).
These cases are extremely rare, which is why you mostly find answers that
"Only explains it with already existing methods and just using async/await pattern"
You can go deeper in The Nature of TaskCompletionSource
Would be nice if you could explain it to me: How to write simple async
method?
First, we need to understand what an async method means. When one exposes an async method to the end user consuming the async method, you're telling him: "Listen, this method will return to you quickly with a promise of completing sometime in the near future". That is what you're guaranteeing to your users.
Now, we need to understand how Task makes this "promise" possible. As you ask in your question, why simply adding a Task.Run inside my method makes it valid to be awaited using the await keyword?
A Task implements the GetAwaiter pattern, meaning it returns an object called an awaiter (Its actually called TaskAwaiter). The TaskAwaiter object implements either INotifyCompletion or ICriticalNotifyCompletion interfaces, exposing a OnCompleted method.
All these goodies are in turn used by the compiler once the await keyword is used. The compiler will make sure that at design time, your object implements GetAwaiter, and in turn use that to compile the code into a state machine, which will enable your program to yield control back to the caller once awaited, and resume when that work is completed.
Now, there are some guidelines to follow. A true async method doesn't use extra threads behind the scenes to do its job (Stephan Cleary explains this wonderfully in There Is No Thread), meaning that exposing a method which uses Task.Run inside is a bit misleading to the consumers of your api, because they will assume no extra threading involved in your task. What you should do is expose your API synchronously, and let the user offload it using Task.Run himself, controlling the flow of execution.
async methods are primarily used for I/O Bound operations, since these naturally don't need any threads to be consumed while the IO operation is executing, and that is why we see them alot in classes responsible for doing IO operations, such as hard drive calls, network calls, etc.
I suggest reading the Parallel PFX teams article Should I expose asynchronous wrappers for synchronous methods? which talks exactly about what you're trying to do and why it isn't recommended.
TL;DR:
Task.Run() is what you want, but be careful about hiding it in your library.
I could be wrong, but you might be looking for guidance on getting CPU-Bound code to run asynchronously [by Stephen Cleary]. I've had trouble finding this too, and I think the reason it's so difficult is that's kinda not what you're supposed to do for a library - kinda...
Article
The linked article is a good read (5-15 minutes, depending) that goes into a decent amount of detail about the hows and whys of using Task.Run() as part of an API vs using it to not block a UI thread - and distinguishes between two "types" of long-running process that people like to run asynchronously:
CPU-bound process (one that is crunching / actually working and needs a separate thread to do its work)
Truly asynchronous operation (sometimes called IO-bound - one that is doing a few things here and there with a bunch of waiting time in between actions and would be better off not hogging a thread while it's sitting there doing nothing).
The article touches on the use of API functions in various contexts, and explains whether the associated architectures "prefer" sync or async methods, and how an API with sync and async method signatures "looks" to a developer.
Answer
The last section "OK, enough about the wrong solutions? How do we fix this the right way???" goes into what I think you're asking about, ending with this:
Conclusion: do not use Task.Run in the implementation of the method; instead, use Task.Run to call the method.
Basically, Task.Run() 'hogs' a thread, and is thus the thing to use for CPU-bound work, but it comes down to where it's used. When you're trying to do something that requires a lot of work and you don't want to block the UI Thread, use Task.Run() to run the hard-work function directly (that is, in the event handler or your UI based code):
class MyService
{
public int CalculateMandelbrot()
{
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
return 42;
}
}
...
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => myService.CalculateMandelbrot());
}
But... don't hide your Task.Run() in an API function suffixed -Async if it is a CPU-bound function, as basically every -Async function is truly asynchronous, and not CPU-bound.
// Warning: bad code!
class MyService
{
public int CalculateMandelbrot()
{
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
return 42;
}
public Task<int> CalculateMandelbrotAsync()
{
return Task.Run(() => CalculateMandelbrot());
}
}
In other words, don't call a CPU-bound function -Async, because users will assume it is IO-bound - just call it asynchronously using Task.Run(), and let other users do the same when they feel it's appropriate. Alternately, name it something else that makes sense to you (maybe BeginAsyncIndependentWork() or StartIndependentWorkTask()).

Categories