i have a .net web api 2 method where i am trying to have some part of my code do something in a separate thread, however after I call the .Wait() method on the task it never hits the next line. I must be overlooking something, but I can't seem to find it. Here's a very simple version of the issue. The line Ok() never gets hit. Any suggestions?
public IHttpActionResult Get() {
var attachTask = AttachNewTasksAsync();
//do something else
attachTask.Wait();
return Ok();
}
public async System.Threading.Tasks.Task AttachNewTasksAsync()
{
await System.Threading.Tasks.Task.Delay(10000);
}
Deadlock. Your main thread is waiting for attachTask to finish and attachTask cannot finish, because it is waiting for main thread.
Either add ConfigureAwait(false) to Task.Delay or do it properly and await attachTask
This is how it should be written:
public async Task<IHttpActionResult> Get() {
var attachTask = AttachNewTasksAsync();
//do something else
await attachTask;
return Ok();
}
How to ensure that deadlock will not happen even if someone waits for it synchronously? Use ConfigureAwait(false).
public async System.Threading.Tasks.Task AttachNewTasksAsync()
{
await System.Threading.Tasks.Task.Delay(10000).ConfigureAwait(false);
}
There is probably nothing I can write, that isn't already covered by Stephen Cleary's blog, so I will just leave this link here.
Related
I need to implement a service which fire a start of the processing. But I don't need to wait for result. I can just show the default output and in the background the process will be working.
However I came up to the problem that the code after await is not executed.
I prepared some code to show the idea:
public class HomeController : Controller
{
public ActionResult Deadlock()
{
AsyncCall();
return View();
}
private async Task AsyncCall()
{
await Task.Delay(10000);
var nonreachablePlace = "The breakpoint will not set the execution here";
Do(nonreachablePlace);
}
private void Do(string m)
{
m.Contains("x");
}
}
I know that it looks very bad. But the idea was like:
A thread go to Deadlock method.
The thread go to AsyncCall method synchronously.
Faces the await statement.
Go from the Deadlock method.
Continue main method to the end.
When Task.Delay finished, this thread will come up from the thread pool and continue working.
To my bad 6 step is not processed. I have tried to set up the breakpoint and never got hit.
But if I reduce the time delay and do it in debug I will come to the 6 step.
Enter to the controller's action method
After return from controller's action method
But if I leave only one breakpoint after await, I won't go to the 6 step
var nonreachablePlace = "The breakpoint will not set the execution here";
NOTE:
I append ConfigureAwait(false) to the Task.Delay(). It looks like this:
private async Task AsyncCall()
{
await Task.Delay(10000).ConfigureAwait(false);
var nonreachablePlace = "The breakpoint will not set the execution here";
Do(nonreachablePlace);
}
And now it works as expected.
My question is why does the code not work without ConfigureAwait(false)?
Maybe it somehow related to SynchronizationContext and it is not reachable after the main thread finishes its work. And after that awaitable method tryes to get a context when it has been already disposed (Just my thought)
Use HostingEnvironment.QueueBackgroundWorkItem.
Note this is only available in Classic ASP.NET on .NET Framework (System.Web.dll) and not ASP.NET Core (I forget to what extent it works in ASP.NET Core 1.x and 2.x running on .NET Framework, but anyway).
All you need is this:
using System.Web.Hosting;
public class MyController : Controller
{
[HttpPost( "/foo" )]
public async Task<ActionResult> DoSomething()
{
HostingEnvironment.QueueBackgroundWorkItem( this.DoSomethingExpensiveAsync ); // Pass the method by name or as a `Func<CancellationToken,Task>` delegate.
return this.View();
}
private async Task DoSomethingExpensiveAsync( CancellationToken cancellationToken )
{
await Task.Delay( TimeSpan.FromSeconds( 30 ) );
}
}
You can also use it with non-async workloads:
[HttpPost( "/foo" )]
public async Task<ActionResult> DoSomething()
{
HostingEnvironment.QueueBackgroundWorkItem( this.DoSomethingExpensive ); // Pass the method by name or as a `Action<CancellationToken>` delegate.
return this.View();
}
private void DoSomethingExpensive( CancellationToken cancellationToken )
{
Thread.Sleep( 30 * 1000 ); // NEVER EVER EVER call Thread.Sleep in ASP.NET!!! This is just an example!
}
If you want to start a job normally at first and only finish it in the background if it takes too long, then do this:
[HttpPost( "/foo" )]
public async Task<ActionResult> DoSomething()
{
Task<String> workTask = this.DoSomethingExpensiveAsync( default );
Task timeoutTask = Task.Delay( TimeSpan.FromSeconds( 5 ) );
Task first = await Task.WhenAny( workTask, timeoutTask );
if( first == timeoutTask )
{
// `workTask` is still running, so resume it in the background:
HostingEnvironment.QueueBackgroundWorkItem( async ct => await workTask );
return this.View( "Still working..." );
}
else
{
// `workTask` finished before the timeout:
String result = await workTask; // or just `workTask.Result`.
return this.View( result );
}
}
private async Task<String> DoSomethingExpensiveAsync( CancellationToken cancellationToken )
{
await Task.Delay( TimeSpan.FromSeconds( 30 ) );
return "Explosive bolts, ten thousand volts; At a million miles an hour, Abrasive wheels and molten metals";
}
So Deadlock() calls AsyncCall()
Then AsyncCall() Tells DeadLock() "Okay, well I'm waiting for Task.Delay to count to 10,000 but you can go ahead."
...so AsyncCall() yields the main thread back over to DeadLock().
Now DeadLock() never said anything about waiting on AsyncCall() to finish, so as far as DeadLock() is concerned, AsyncCall() has already returned (it actually only yielded, but the program cursor would still be passed back out into DeadLock().
So I would suggest setting your breakpoint at the AsyncCall() method in DeadLock(), because you'll probably see that your main thread is already done and exited before the Task.Delay() is even done.
So AsyncCall() never even gets a chance to finish Awaiting.
I dived deep into the logic behind Task.Delay(10000) and continuation code after that.
Thanks to the post made by Stephen Toub.
The main problem was in part when a Task had finished. And it's result needed to be processed by next thread.
Since I hadn't written ConfigureAwait() I implicitly meant to run the code in a thread which has SynchronizationContext (AspNetSynchronizationContext in my case).
private async Task AsyncCall()
{
/// The delay is done by a thread from a ThreadPool.
await Task.Delay(10000);
/// After the Task has been finished
/// TaskAwaiter tryies to send a continuation code to a thread with
/// SynchronizationContext.
var nonreachablePlace = "The breakpoint will not set the execution here";
Do(nonreachablePlace);
}
Because I hadn't wanted to wait the result of awaitable, I returned the response from controller's action. Then the thread went to ThreadPool and SynchronizationContext was disposed.
To the moment of Task completion, there was no SynchronizationContext to send a delegate with continuation code.
And during the code creation Visual Studio Enabled Just My Code option was set to true. That's why this exception was thrown silently to me.
And about the situation when I was able to run a code even I had Task.Delay(2000). I think it's caused by the time needed to Classic ASP.NET to complete a request and create a response to it. During this time you can get a reference to SynchronizationContext and Post a delegate to it.
This question already has answers here:
Why use async and return await, when you can return Task<T> directly?
(9 answers)
How and when to use ‘async’ and ‘await’
(25 answers)
Closed 3 years ago.
I was looking at how to use async await, but I do not quite get it when we have multiple methods invoking each other. Should we always use await or should we only use await when we are actually ready to use the result?
So for example should we do it like this:
async Task<string[]> FooAsync()
{
var info = await Func1();
return info.split('.');
}
async Task<string> Func1()
{
return await Func2();
}
async Task<string> Func2()
{
return await tcpClient.ReadStringAsync();
}
Or like this:
async Task<string[]> FooAsync()
{
var info = await Func1();
return info.split('.');
}
Task<string> Func1()
{
return Func2();
}
Task<string> Func2()
{
return tcpClient.ReadStringAsync();
}
Per example 1, should we always use await in every method?
Or
Per example 2 should we only use await on the top-most method when we start using the result?
Every-time you call await it creates a lump of code to bundle up variables, captures the synchronization context (if applicable) and create a continuation into an IAsyncStateMachine.
Essentially, returning a Task without the async keyword will give you a small run-time efficiency and save you a bunch of CIL. Do note that the Async feature in .NET also has many optimizations already. Also note (and importantly) that returning a Task in a using statement will likely throw an Already Disposed Exception.
You can compare the CIL and plumbing differences here
Forwarded Task
Async Method
So if your method is just forwarding a Task and not wanting anything from it, you could easily just drop the async keyword and return the Task directly.
More-so, there are times when we do more than just forwarding and there is branching involved. This is where, Task.FromResult and Task.CompletedTask come into play to help deal with the logic of what may arise in a method. I.e If you want to give a result (there and then), or return a Task that is completed (respectively).
Lastly, the Async and Await Pattern has subtle differences when dealing with Exceptions. If you are returning a Task, you can use Task.FromException<T> to pop any exception on the the returned Task like an async method would normally do.
Nonsensical example
public Task<int> DoSomethingAsync(int someValue)
{
try
{
if (someValue == 1)
return Task.FromResult(3); // Return a completed task
return MyAsyncMethod(); // Return a task
}
catch (Exception e)
{
return Task.FromException<int>(e); // Place exception on the task
}
}
In short, if you don't quite understand what is going on, just await it; the overhead will be minimal. However, if you understand the subtitles of how to return a task result, a completed task, placing an exception on a task, or just forwarding. You can save your self some CIL and give your code a small performance gain by dropping the async keyword returning a task directly and bypassing the IAsyncStateMachine.
At about this time, I would look up the Stack Overflow user and author Stephen Cleary, and Mr. Parallel Stephen Toub. They have a plethora of blogs and books dedicated solely to the Async and Await Pattern, all the pitfalls, coding etiquette and lots more information you will surely find interesting.
Both options are legit and each option has own scenarios where it is more effective then another.
Of course always use await when you want to handle result of the asynchronous method or handle possible exception in current method
public async Task Execute()
{
try
{
await RunAsync();
}
catch (Exception ex)
{
// Handle thrown exception
}
}
If you don't use result of asynchronous method in current method - return the Task. This approach will delay state machine creation to the caller or where ever final task will be awaited. As pointed in the comments can make execution little bit more effective.
But there are scenarios where you must await for the task, even you do nothing with result and don't want handle possible exceptions
public Task<Entity> GetEntity(int id)
{
using (var context = _contextFactory.Create())
{
return context.Entities.FindAsync(id);
}
}
In the scenario above, FindAsync can return not completed task and this task will be returned straight away to the caller and dispose context object created within using statement.
Later when caller will "await" for the task exception will be thrown because it will try to use already disposed object(context).
public async Task<Entity> GetEntity(int id)
{
using (var context = _contextFactory.Create())
{
return await context.Entities.FindAsync(id);
}
}
And traditionally answers about Async Await must include link to Stephen Cleary's blog
Eliding Async and Await
Await is a sequencing feature which allows the caller to receive the result of an async method and do something with it. If you do not need to process the result of an async function, you do not have to await it.
In your example Func1() and Func2() do no process the return values of the called async functions, so it is fine not to await them.
When you use await the code will wait for the async function to finish. This should be done when you need a value from an async function, like this case:
int salary = await CalculateSalary();
...
async Task<int> CalculateSalary()
{
//Start high cpu usage task
...
//End high cpu usage task
return salary;
}
If you hadn't use the the await this would happen:
int salary = CalculateSalary().Result;
...
async Task<int> CalculateSalary()
{
//Start high cpu usage task
... //In some line of code the function finishes returning null because we didn't wait the function to finish
return salary; //This never runs
}
Await means, wait this async function to finish.
Use it to your needs, your case 1 and 2 would produce the same result, as long as you await when you assign the info value the code will be safe.
Source: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/index
I believe the 2nd one will do because await is expecting a return value.
Since it is waiting for the Func1() to return a value, Func1() is already executing Func2() which is returning a value.
In my current project, I have a piece of code that, after simplifying it down to where I'm having issues, looks something like this:
private async Task RunAsync(CancellationToken cancel)
{
bool finished = false;
while (!cancel.IsCancellationRequested && !finished)
finished = await FakeTask();
}
private Task<bool> FakeTask()
{
return Task.FromResult(false);
}
If I use this code without awaiting, I end up blocking anyway:
// example 1
var task = RunAsync(cancel); // Code blocks here...
... // Other code that could run while RunAsync is doing its thing, but is forced to wait
await task;
// example 2
var task = RunAsync(cancelSource.Token); // Code blocks here...
cancelSource.Cancel(); // Never called
In the actual project, I'm not actually using FakeTask, and there usually will be some Task.Delay I'm awaiting in there, so the code most of the time doesn't actually block, or only for a limited amount of iterations.
In unit testing, however, I'm using a mock object that does pretty much do what FakeTask does, so when I want to see if RunAsync responds to its CancellationToken getting cancelled the way I expect it to, I'm stuck.
I have found I can fix this issue by adding for example await Task.Delay(1) at the top of RunAsync, to force it to truly run asynchronous, but this feels a bit hacky. Are there better alternatives?
You have an incorrect mental picture of what await does. The meaning of await is:
Check to see if the awaitable object is complete. If it is, fetch its result and continue executing the coroutine.
If it is not complete, sign up the remainder of the current method as the continuation of the awaitable and suspend the coroutine by returning control to the caller. (Note that this makes it a semicoroutine.)
In your program, the "fake" awaitable is always complete, so there is never a suspension of the coroutine.
Are there better alternatives?
If your control flow logic requires you to suspend the coroutine then use Task.Yield.
Task.FromResult actually runs synchronously, as would await Task.Delay(0). If you want to actually simulate asynchronous code, call Task.Yield(). That creates an awaitable task that asynchronously yields back to the current context when awaited.
As #SLaks said, your code will run synchronously. One thing is running async code, and another thing is running parallel code.
If you need to run your code in parallel you can use Task.Run.
class Program
{
static async Task Main(string[] args)
{
var tcs = new CancellationTokenSource();
var task = Task.Run(() => RunAsync("1", tcs.Token));
var task2 = Task.Run(() => RunAsync("2", tcs.Token));
await Task.Delay(1000);
tcs.Cancel();
Console.ReadLine();
}
private static async Task RunAsync(string source, CancellationToken cancel)
{
bool finished = false;
while (!cancel.IsCancellationRequested && !finished)
finished = await FakeTask(source);
}
private static Task<bool> FakeTask(string source)
{
Console.WriteLine(source);
return Task.FromResult(false);
}
}
C#'s async methods execute synchronously up to the point where they have to wait for a result.
In your example there is no such point where the method has to wait for a result, so the loop keeps running forever and thereby blocking the caller.
Inserting an await Task.Yield() to simulate some real async work should help.
What is the best practice when returning the following Task:
public async Task<Command> BuildCommunicationCommand
As an object:
public Command BuildCommand
I have the following:
public Command BuildCommand()
{
return BuildCommunicationCommand().GetAwaiter().GetResult();
}
But have been told to try and avoid this and that I should await the Task so we do not block the UI thread. I think the best way to do this is to make the BuildCommand method async and anything else that calls it. This would be a massive change and is not really required for other classes which use the BuildCommand. I do not want to cause a block by using .Result so have read its best to use ConfigureAwait(false) in this case:
public Command BuildCommand()
{
var Command = BuildCommunicationCommand().ConfigureAwait(false);
return Command.GetAwaiter().GetResult();
}
Can I use ConfigureAwait(false) to wait for the process to finish and then call .GetAwaiter().GetResult() to return it as the object Command?
This is my first time working with async tasks so if any of the above is complete rubbish I am sorry!
You can wrap the call to your async method in another method that waits for the task to complete and then returns the result. Of course that blocks the thread that calls GetData. But it gets rid of the async 'virus'. Something like this:
private string GetData()
{
var task = GetDataAsync();
task.Wait();
return task.Result;
}
private async Task<string> GetDataAsync()
{
return "Hello";
}
You're asking after best practices though, and that is to change everything to async as needed.
For example, in the code below, the last method M2Async is synchronous and does not have async/await as otherwise there would need to be a call to M3Async after await and the call graph would continue?
For clarity (from C# in a Nutshell):
A synchronous operation does its work before returning to the caller.
An asynchronous operation does (most or all of) its work after returning to the caller.
public void Main()
{
Task task = M1Async();
// some work
int i = task.result;
// use i etc
}
private async Task M1Async()
{
int i = await M2Async();
// some work
return i;
}
private Task M2Async()
{
return Task.FromResult(2);
}
That depends a bit on what you mean by "synchronous". In some ways, all methods are synchronous (even async ones) - they just synchronously return something that can be awaited and which might have more things to do once awaited.
No, it doesn't have to be synchronous; your code could just as well be:
private async Task<int> M2Async()
{
return await Task.FromResult(2);
}
or even just (although the compiler will detect that this is a smell, and is secretly synchronous):
private async Task<int> M2Async()
{
return 2;
}
Neither of which would be particularly useful, but; they would work. In reality, most async methods will bottom out at something that is doing async IO - file-system, network, etc. In your example, there is nothing that will actually truly be async anyway - it will all be completed when the await is reached.