Write your own async method - c#

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()).

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.

Understanding Async/await properly. How is it correct?

Imagine the following situation. There is an UI and s long running operation must be called without blocking the Main thread. the long running operation calls intself some other methods, which don't interact with the UI thread.
In Most cases, the methods which are called from Method B and C have synchronous alternatives to their Async counterparts. The question is: can they be used safely instead of their async counterpart? Lets say DbContext.DbSet.Add instead of AddAsync
// UI
public async Task UiMethodAsync()
{
var result = await MethodAAsync();
}
// some component
public async Task<bool> MethodAAsync()
{
return await MethodBAsync().ConfigureAwait(false);
}
public async Task<bool> MethodBAsync()
{
return await MethodCAsync().ConfigureAwait(false);
}
public async Task<bool> MethodCAsync()
{
return await DbContext.Set<TEntit>.AnyAsync().ConfigureAwait(false);
}
My question is: Is it neccessary to make all the methods asynchronous to prevent UI thread from blocking or would it be eben good enough to make Method B and C synchronously like this:
// UI
public async Task UiMethodAsync()
{
var result = await MethodAAsync();
}
// some component
public Task<bool> MethodAAsync()
{
return Task.FromResult(MethodB());
}
public bool MethodB()
{
return MethodC();
}
public bool MethodC()
{
return DbContext.Set<TEntit>.Any();
}
of course this depends on what MethodB and C are doing, if they interact with the ui thread or not. but let's say they don't and just have to calculate things and return a result.
Is there a need to make them asynchronous as well? I guess no. I think it probably avoids unnecessary overhead for managing tasks and threads.
A method that returns a Task creates the expectation that will not block the calling thread. At least not for a substantial amount of time. But this is not enforced by the async-await machinery. It is possible, and actually very easy, to write a method that breaks this expectation. For example:
public Task DoStuffTheWrongWayAsync()
{
Thread.Sleep(1000); // Simulate a heavy computation, or a blocking call
return Task.CompletedTask;
}
Any thread that calls this method will be blocked for one second, and then will be handed a completed task. I don't know if this antipattern has an established name. Fake-asynchrony comes in mind, although this can also be used for the case that the caller is not blocked, but another poor thread is blocked instead. The bottom line is that a well behaved asynchronous method should return a Task immediately, leaving the calling thread free to do other work (like responding to UI events if it's a UI thread).
Just adding the async keyword is not enough to make your code not block.
A function returning a Task will still block unless the calls are async all the way down.
It's difficult to explain, but to highlight one bit of your code:
public async Task<bool> MethodA()
{
return Task.FromResult(MethodB());
}
Is equivalent to
public async Task<bool> MethodA()
{
bool b = MethodB();
return Task.FromResult(b);
}
It is clear now that the first line of code is blocking, and the Task isn't created until the second line.
Generally speaking, if you want to make something asynchronous, you start at the lowest level - the APIs that are actually doing I/O work. In your example, AnyAsync would be the first thing made asynchronous. Then allow the asynchrony to grow from there (up through MethodC, then MethodB, then MethodA, and finally UiMethod).
It is normal to end up with asynchrony going "all the way".
Is there a need to make them asynchronous as well? I guess no.
Yes. If you want them to be asynchronous, then they need to be asynchronous. Task.FromResult is for synchronous implementations; they won't be asynchronous.
Imagine the following situation. There is an UI... the methods which are called from Method B and C have synchronous alternatives to their Async counterparts. The question is: can they be used safely instead of their async counterpart?
One thing you can get away with in UI world is by wrapping calls to synchronous methods in Task.Run. E.g.:
public async Task UiMethodAsync()
{
var result = await Task.Run(MethodA);
}
This is a useful technique for situations where you have a client-side app, don't want to block the UI, but also don't want to take the time to convert all the code to being asynchronous. Note that this is not appropriate for server-side applications such as ASP.NET.

Why use async when I have to use await?

I've been stuck on this question for a while and haven't really found any useful clarification as to why this is.
If I have an async method like:
public async Task<bool> MyMethod()
{
// Some logic
return true;
}
public async void MyMethod2()
{
var status = MyMethod(); // Visual studio green lines this and recommends using await
}
If I use await here, what's the point of the asynchronous method? Doesn't it make the async useless that VS is telling me to call await? Does that not defeat the purpose of offloading a task to a thread without waiting for it to finish?
Does that not defeat the purpose of offloading a task to a thread without waiting for it to finish?
Yes, of course. But that's not the purpose of await/async. The purpose is to allow you to write synchronous code that uses asynchronous operations without wasting threads, or more generally, to give the caller a measure of control over the more or less asynchronous operations.
The basic idea is that as long as you use await and async properly, the whole operation will appear to be synchronous. This is usually a good thing, because most of the things you do are synchronous - say, you don't want to create a user before you request the user name. So you'd do something like this:
var name = await GetNameAsync();
var user = await RemoteService.CreateUserAsync(name);
The two operations are synchronous with respect to each other; the second doesn't (and cannot!) happen before the first. But they aren't (necessarily) synchronous with respect to their caller. A typical example is a Windows Forms application. Imagine you have a button, and the click handler contains the code above - all the code runs on the UI thread, but at the same time, while you're awaiting, the UI thread is free to do other tasks (similar to using Application.DoEvents until the operation completes).
Synchronous code is easier to write and understand, so this allows you to get most of the benefits of asynchronous operations without making your code harder to understand. And you don't lose the ability to do things asynchronously, since Task itself is just a promise, and you don't always have to await it right away. Imagine that GetNameAsync takes a lot of time, but at the same time, you have some CPU work to do before it's done:
var nameTask = GetNameAsync();
for (int i = 0; i < 100; i++) Thread.Sleep(100); // Important busy-work!
var name = await nameTask;
var user = await RemoteService.CreateUserAsync(name);
And now your code is still beautifuly synchronous - await is the synchronization point - while you can do other things in parallel with the asynchronous operations. Another typical example would be firing off multiple asynchronous requests in parallel but keeping the code synchronous with the completion of all of the requests:
var tasks = urls.Select(i => httpClient.GetAsync(i)).ToArray();
await Task.WhenAll(tasks);
The tasks are asynchronous in respect to each other, but not their caller, which is still beautifuly synchronous.
I've made a (incomplete) networking sample that uses await in just this way. The basic idea is that while most of the code is logically synchronous (there's a protocol to be followed - ask for login->verify login->read loop...; you can even see the part where multiple tasks are awaited in parallel), you only use a thread when you actually have CPU work to do. Await makes this almost trivial - doing the same thing with continuations or the old Begin/End async model would be much more painful, especially with respect to error handling. Await makes it look very clean.
If I use await here, what's the point of the asynchronous method?
await does not block thread. MyMethod2 will run synchronously until it reaches await expression. Then MyMethod2 will be suspended until awaited task (MyMethod) is complete. While MyMethod is not completed control will return to caller of MyMethod2. That's the point of await - caller will continue doing it's job.
Doesn't it make the async useless that VS is telling me to call await?
async is just a flag which means 'somewhere in the method you have one or more await'.
Does that not defeat the purpose of offloading a task to a thread
without waiting for it to finish?
As described above, you don't have to wait for task to finish. Nothing is blocked here.
NOTE: To follow framework naming standards I suggest you to add Async suffix to asynchronous method names.
An async method is not automatically executed on a different thread. Actually, the opposite is true: an async method is always executed in the calling thread. async means that this is a method that can yield to an asynchronous operation. That means it can return control to the caller while waiting for the other execution to complete. So asnync methods are a way to wait for other asynchronoous operations.
Since you are doing nothing to wait for in MyMethod2, async makes no sense here, so your compiler warns you.
Interestingly, the team that implemented async methods has acknowledged that marking a method async is not really necessary, since it would be enough to just use await in the method body for the compiler to recognize it as async. The requirement of using the async keyword has been added to avoid breaking changes to existing code that uses await as a variable name.

Why use Async/await all the way down

I would like to get some clarification on what is the added benefit of using of Await and Async all the way down.
If my application is calling await Func1() (So no blocking to the UI here). and Func1 is calling await Func2(), but the results from Func2() are important for Func1 to complete it's job, then why would I need to make Func2() awaitable. Func1() execution will take just as long because it's waiting on Func2 to finish. All what the await is doing here is adding the StateMachine overhead.
Am I missing something here?
A better slogan is async all the way up. Because you start with an asynchronous operation and make its caller asynchronous and then the next caller etc.
You should use async-await when you have an inherently asynchronous operation (usually I/O but not necessarily) and you don't want to waste a thread idly waiting for the operation to complete. Choosing an async operation instead of a synchronous one doesn't speed up the operation. It will take the same amount of time (or even more). It just enables that thread to continue executing some other CPU bound work instead of wasting resources.
But to be able to await that operation the method needs to be an async one and the caller needs to await it and so forth and so forth.
So async all the way up enables you to actually make an asynchronous call and release any threads. If it isn't async all the way then some thread is being blocked.
So, this:
async Task FooAsync()
{
await Func1();
// do other stuff
}
async Task Func1()
{
await Func2();
// do other stuff
}
async Task Func2()
{
await tcpClient.SendAsync();
// do other stuff
}
Is better than this:
void Foo()
{
Func1();
// do other stuff
}
void Func1()
{
Func2().Wait(); // Synchronously blocking a thread.
// do other stuff
}
async Task Func2()
{
await tcpClient.SendAsync();
// do other stuff
}
The major benefit is the fact that awaiting an asynchronous method returns the worker thread to the pool to be used in other calls (web requests to your .NET MVC web app, for example). The asynchronous work is done on an IO completion thread. When the awaited method finishes, another worker thread will collect the results and resume execution. This prevents worker thread pool exhaustion and allows your application to handle more load (CPU, memory, and network throughput depending).
As for "await all the way down", that seems like an issue to me. Typically await is associated to an external resource (DB call, HTTP request, etc.) that your application must wait on. If you await code that doesn't have external IO dependencies, you're creating overhead that isn't needed. It's possible to have multiple awaits in an async method chain, but awaiting some code that itself calls await but has no other external IO dependency is not good and will just add callback/compiler overhead.
Usually, the reasoning behind async/await goes the other way around:
For whatever reason, you decide that Func2 would be easier to write using await. So you simplify the method by adding the desired awaits, meaning you also have to change the method signature (it will now include the async keyword and a return type of Task or Task<T>).
Because the return type has changed, you can no longer call Func2 like you used to (var result = Func2();), so you're now required to change the calling method, Func1. The easiest way to adapt Func1 will often be to make it async too, and await Func2().
Then, for the same reason (changed signature), you will need to change all calls to Func1, and so on until you get to some kind of entry point (either a UI event handler, or your Main method, or something else).
So you don't start making the "outermost" method async and follow through to the "inner" (called) methods; you usually make things async while going in the opposite direction (from the "innermost" methods back to the calling ones). This other answer calls this idea "async all the way up".
"This async method lacks 'await' operators and will run synchronously" is what happens if you don't await an async method. To harness the benefits of an async method you must await it, turning the caller into an async method which can be awaited etc etc.
From the flow diagram you see that the async method returns a Task (a promise of work to be completed in the future) and yields control to it's caller. The caller can then get on with work not dependent on this result in the meantime. Clearly this needs to bubble up the call stack to find all of this gainful work that can be done without the result (In a UI app this work would include unblocking the UI, which is why it's async all the way up to the the event handler in the below example).
From my initial misreading. So you've found some async code that you need to call, is it worth the async await pattern spreading up your code:
I've heard a lot that the main problem with async-await is it's a much too easy syntax for what it actually does. Program flow gets complicated. I really like async-await, but unfortunately in most the async code I've seen it isn't worth it and is just needlessly ruining my call-stack.
A good thing to keep in mind is the 50ms rule.
"This is the rule that Microsoft followed with the WinRT APIs; anything taking less than 50ms is considered “fast” and close enough to “immediate” that they do not require an asynchronous API."
This is being used in the context of encouraging async-await. However, I think it equally should be applied to tell developers using async-await for essentially immediate functionality to cut it out.
In a UI based application async await provides a very succinct way to handle asynchronous calls resulting in UI updates. If the 'top level' handler from the UI is awaiting a result then there is potentially no real benefit in the whole chain down doing the same unless it makes sense to do so. A design goal of async await was to make async programming look more synchronous and continuous and not have callbacks scattered around etc - making async coding more assessable. It's not something you need to use everywhere arbitrarily.

Async controller method not returning

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

Categories