ASP.NET MVC Async Action doesn't work properly - c#

I have an issue with this simple async code. The execution goes througth the TestAsync action and goes througth the delay method but when the delay method returns nothing else happens.
it seems like blocked for some reason.
public async Task<ActionResult> TestAsync()
{
try
{
var res = await doLongOperation();
return RedirectToAction("Index");
}
catch (Exception e) { }
}
private Task<bool> doLongOperation()
{
var test = new Task<bool>(() => { /*do the long operation..*/ return true; });
return test;
}
Any suggestion?

new Task<bool>(() => true) returns a task that is not started yet. This is an old syntax that requires you to invoke the Start method on the task. If you don't invoke the Start method, the task will never complete, and thus asynchronous execution will never continue (await will asynchronously wait forever).
If you simply want to delay execution, then simply use Task.Delay like this:
private async Task<bool> delay()
{
await Task.Delay(1000);
return true;
}
In general, it is always recommended to create tasks that are already started upon creation.
If you want to create a task that runs on a thread-pool thread, then use the Task.Run method.

The method posted in your question doesn't work properly because the task is not started, there's nothing finishing so your await is waiting indefinitely. If you want to use Async it's best to use async all the way down, especially in an ASP.NET context. If you are not doing anything that is truly asynchronous, then in a web development context, just allow it to be synchronous.
I honestly believe the most good that will be done here is for you to spend time studying async/await, an excellent resource is found here: Stephen Cleary Blog on Async

Related

Can't await task on MainWindow Loaded event [duplicate]

I don't quite understand the difference between Task.Wait and await.
I have something similar to the following functions in a ASP.NET WebAPI service:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
Where Get will deadlock.
What could cause this? Why doesn't this cause a problem when I use a blocking wait rather than await Task.Delay?
Wait and await - while similar conceptually - are actually completely different.
Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use "async all the way down"; that is, don't block on async code. On my blog, I go into the details of how blocking in asynchronous code causes deadlock.
await will asynchronously wait until the task completes. This means the current method is "paused" (its state is captured) and the method returns an incomplete task to its caller. Later, when the await expression completes, the remainder of the method is scheduled as a continuation.
You also mentioned a "cooperative block", by which I assume you mean a task that you're Waiting on may execute on the waiting thread. There are situations where this can happen, but it's an optimization. There are many situations where it can't happen, like if the task is for another scheduler, or if it's already started or if it's a non-code task (such as in your code example: Wait cannot execute the Delay task inline because there's no code for it).
You may find my async / await intro helpful.
Based on what I read from different sources:
An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
To wait for a single task to complete, you can call its Task.Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The parameterless Wait() method is used to wait unconditionally until a task completes. The task simulates work by calling the Thread.Sleep method to sleep for two seconds.
This article is also a good read.
Some important facts were not given in other answers:
async/await is more complex at CIL level and thus costs memory and CPU time.
Any task can be canceled if the waiting time is unacceptable.
In the case of async/await we do not have a handler for such a task to cancel it or monitoring it.
Using Task is more flexible than async/await.
Any sync functionality can by wrapped by async.
public async Task<ActionResult> DoAsync(long id)
{
return await Task.Run(() => { return DoSync(id); } );
}
async/await generate many problems. We do not know if await statement will be reached without runtime and context debugging. If first await is not reached, everything is blocked. Sometimes even when await seems to be reached, still everything is blocked:
https://github.com/dotnet/runtime/issues/36063
I do not see why I must live with the code duplication for sync and async method or using hacks.
Conclusion: Creating Tasks manually and controlling them is much better. Handler to Task gives more control. We can monitor Tasks and manage them:
https://github.com/lsmolinski/MonitoredQueueBackgroundWorkItem
Sorry for my english.

SendGrid hanging only in web app (not in console app) [duplicate]

I don't quite understand the difference between Task.Wait and await.
I have something similar to the following functions in a ASP.NET WebAPI service:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
Where Get will deadlock.
What could cause this? Why doesn't this cause a problem when I use a blocking wait rather than await Task.Delay?
Wait and await - while similar conceptually - are actually completely different.
Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use "async all the way down"; that is, don't block on async code. On my blog, I go into the details of how blocking in asynchronous code causes deadlock.
await will asynchronously wait until the task completes. This means the current method is "paused" (its state is captured) and the method returns an incomplete task to its caller. Later, when the await expression completes, the remainder of the method is scheduled as a continuation.
You also mentioned a "cooperative block", by which I assume you mean a task that you're Waiting on may execute on the waiting thread. There are situations where this can happen, but it's an optimization. There are many situations where it can't happen, like if the task is for another scheduler, or if it's already started or if it's a non-code task (such as in your code example: Wait cannot execute the Delay task inline because there's no code for it).
You may find my async / await intro helpful.
Based on what I read from different sources:
An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
To wait for a single task to complete, you can call its Task.Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The parameterless Wait() method is used to wait unconditionally until a task completes. The task simulates work by calling the Thread.Sleep method to sleep for two seconds.
This article is also a good read.
Some important facts were not given in other answers:
async/await is more complex at CIL level and thus costs memory and CPU time.
Any task can be canceled if the waiting time is unacceptable.
In the case of async/await we do not have a handler for such a task to cancel it or monitoring it.
Using Task is more flexible than async/await.
Any sync functionality can by wrapped by async.
public async Task<ActionResult> DoAsync(long id)
{
return await Task.Run(() => { return DoSync(id); } );
}
async/await generate many problems. We do not know if await statement will be reached without runtime and context debugging. If first await is not reached, everything is blocked. Sometimes even when await seems to be reached, still everything is blocked:
https://github.com/dotnet/runtime/issues/36063
I do not see why I must live with the code duplication for sync and async method or using hacks.
Conclusion: Creating Tasks manually and controlling them is much better. Handler to Task gives more control. We can monitor Tasks and manage them:
https://github.com/lsmolinski/MonitoredQueueBackgroundWorkItem
Sorry for my english.

Different Behavior with wait than await [duplicate]

I don't quite understand the difference between Task.Wait and await.
I have something similar to the following functions in a ASP.NET WebAPI service:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
Where Get will deadlock.
What could cause this? Why doesn't this cause a problem when I use a blocking wait rather than await Task.Delay?
Wait and await - while similar conceptually - are actually completely different.
Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use "async all the way down"; that is, don't block on async code. On my blog, I go into the details of how blocking in asynchronous code causes deadlock.
await will asynchronously wait until the task completes. This means the current method is "paused" (its state is captured) and the method returns an incomplete task to its caller. Later, when the await expression completes, the remainder of the method is scheduled as a continuation.
You also mentioned a "cooperative block", by which I assume you mean a task that you're Waiting on may execute on the waiting thread. There are situations where this can happen, but it's an optimization. There are many situations where it can't happen, like if the task is for another scheduler, or if it's already started or if it's a non-code task (such as in your code example: Wait cannot execute the Delay task inline because there's no code for it).
You may find my async / await intro helpful.
Based on what I read from different sources:
An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
To wait for a single task to complete, you can call its Task.Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The parameterless Wait() method is used to wait unconditionally until a task completes. The task simulates work by calling the Thread.Sleep method to sleep for two seconds.
This article is also a good read.
Some important facts were not given in other answers:
async/await is more complex at CIL level and thus costs memory and CPU time.
Any task can be canceled if the waiting time is unacceptable.
In the case of async/await we do not have a handler for such a task to cancel it or monitoring it.
Using Task is more flexible than async/await.
Any sync functionality can by wrapped by async.
public async Task<ActionResult> DoAsync(long id)
{
return await Task.Run(() => { return DoSync(id); } );
}
async/await generate many problems. We do not know if await statement will be reached without runtime and context debugging. If first await is not reached, everything is blocked. Sometimes even when await seems to be reached, still everything is blocked:
https://github.com/dotnet/runtime/issues/36063
I do not see why I must live with the code duplication for sync and async method or using hacks.
Conclusion: Creating Tasks manually and controlling them is much better. Handler to Task gives more control. We can monitor Tasks and manage them:
https://github.com/lsmolinski/MonitoredQueueBackgroundWorkItem
Sorry for my english.

Does Task.Result have any impact when used after the await statement?

I'm trying to work on a proof of concept app, and I would like to know the internals of below two Async Methods.
Would Task.Result cause any issues in DoSomethingAsync1()?
I've read a bit about some blocking and deadlock issues that Task.Result can cause, but I think it wouldn't in this case, since it runs on a separate task and there is an await on the task which already ensures the Result.
The main goal here is to run the async method on a separate task, since this operation doesn't depend on main asp.net thread, and more importantly catch any exceptions thrown by DoSomethingThatTakesReallyLong()
Also,in the ActionResult DoSomething(), should I set .ConfigureAwait(false);?
Are there any hidden bottlenecks/issues that I need to be aware of in the below scenario?
Update
I've fixed the typo I made when typing the question here. (returning user object instead of a task)
Also, I'm not at the liberty of converting all the higher level methods to async at one go in the actual application. So, this is something I'm planning to do in a step-by-step way, starting with operations that doesn't depend on main thread.
I really appreciate all the best-practices answers as well, but this being a little playground code, my main question was to know if there are internal differences between DoSomethingAsync1() and DoSomethingAsync2() that might cause any issues under a certain condition.
From reading through the comments and answers, I get an idea that there isn't much difference.
private static async Task<User> DoSomethingAsync1()
{
try
{
var longRunningTask = Task<User>.Factory.StartNew(() => LongRunner.LongRunnerInstance.DoSomethingThatTakesReallyLong());
var user = await longRunningTask;
//Will the below line of code cause any issue?
Console.WriteLine(longRunningTask.Result.Id);
return user;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
}
private static async Task<User> DoSomethingAsync2()
{
try
{
var longRunningTask = Task<User>.Factory.StartNew(() => LongRunner.LongRunnerInstance.DoSomethingThatTakesReallyLong());
var user = await longRunningTask;
Console.WriteLine(user.Id);
return user;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
}
public ActionResult Index()
{
//Things that run on main Asp.NET thread
//Things that run independently
//Won't be using the task returned here at the moment.
DoSomethingAsync1();
//Do more things on main Asp.NET thread if needed
return View();
}
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
Thanks
Would Task.Result cause any issues [if the task is already completed]?
Task<T>.Result will synchronously wait for the task to complete (the same as task.Wait()), and then return the result (the same as await task).
Since your task is already completed, there is only one other difference between Result and await that is important: Result will wrap exceptions in an AggregateException. For this reason (and also to make the code more refactor-safe), I use await instead of Result whenever possible. That is, take the DoSomethingAsync2 approach.
I've read a bit about some blocking and deadlock issues that Task.Result can cause, but I think it wouldn't in this case, since it runs on a separate task and there is an await on the task which already ensures the Result.
It wouldn't because it's running in the thread pool context.
So, this is something I'm planning to do in a step-by-step way, starting with operations that doesn't depend on main thread.
You may find my brownfield async article helpful. In that article, I refer to this technique as "The Thread Pool Hack".
Are there any hidden bottlenecks/issues that I need to be aware of in the below scenario?
A few:
You shouldn't use StartNew. Use Task.Run instead.
You shouldn't fire-and-forget on ASP.NET (i.e., call an asynchronous method without consuming its task).
You shouldn't expose fake-asynchronous methods (i.e., methods with an asynchronous signature but that are implemented by blocking a thread pool thread). Instead of using Task.Run to implement a method, use Task.Run to call a method.
Combining those three points, the proper structure of The Thread Pool Hack is to use Task.Run with GetAwaiter().GetResult() (which is just like Result but avoids the AggregateException wrapper):
public ActionResult Index()
{
var r = Task.Run(() => LongRunner.LongRunnerInstance.DoSomethingThatTakesReallyLong())
.GetAwaiter().GetResult();
return View();
}
As a final issue, as long as you have this pattern in your ASP.NET application, the scalability of your application will be decreased. Instead of using one thread during DoSomethingThatTakesReallyLong, your app is now using two; this may also throw off the ASP.NET thread pool heuristics. This may be acceptable during the transition to async, but keep it in mind as a motivator to finish the transition.
A normal usage would be something like this:
private static async Task<User> DoSomethingAsync3()
{
try
{
var user = await Task.Run(() => LongRunner.LongRunnerInstance.DoSomethingThatTakesReallyLong());
Console.WriteLine(user.Id);
return user;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Also, if you were to correctly follow the async all the way pattern, you should change your Index to this:
public async Task<ActionResult> Index()
{
await DoSomethingAsync3();
return View();
}

await vs Task.Wait - Deadlock?

I don't quite understand the difference between Task.Wait and await.
I have something similar to the following functions in a ASP.NET WebAPI service:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
Where Get will deadlock.
What could cause this? Why doesn't this cause a problem when I use a blocking wait rather than await Task.Delay?
Wait and await - while similar conceptually - are actually completely different.
Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use "async all the way down"; that is, don't block on async code. On my blog, I go into the details of how blocking in asynchronous code causes deadlock.
await will asynchronously wait until the task completes. This means the current method is "paused" (its state is captured) and the method returns an incomplete task to its caller. Later, when the await expression completes, the remainder of the method is scheduled as a continuation.
You also mentioned a "cooperative block", by which I assume you mean a task that you're Waiting on may execute on the waiting thread. There are situations where this can happen, but it's an optimization. There are many situations where it can't happen, like if the task is for another scheduler, or if it's already started or if it's a non-code task (such as in your code example: Wait cannot execute the Delay task inline because there's no code for it).
You may find my async / await intro helpful.
Based on what I read from different sources:
An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
To wait for a single task to complete, you can call its Task.Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The parameterless Wait() method is used to wait unconditionally until a task completes. The task simulates work by calling the Thread.Sleep method to sleep for two seconds.
This article is also a good read.
Some important facts were not given in other answers:
async/await is more complex at CIL level and thus costs memory and CPU time.
Any task can be canceled if the waiting time is unacceptable.
In the case of async/await we do not have a handler for such a task to cancel it or monitoring it.
Using Task is more flexible than async/await.
Any sync functionality can by wrapped by async.
public async Task<ActionResult> DoAsync(long id)
{
return await Task.Run(() => { return DoSync(id); } );
}
async/await generate many problems. We do not know if await statement will be reached without runtime and context debugging. If first await is not reached, everything is blocked. Sometimes even when await seems to be reached, still everything is blocked:
https://github.com/dotnet/runtime/issues/36063
I do not see why I must live with the code duplication for sync and async method or using hacks.
Conclusion: Creating Tasks manually and controlling them is much better. Handler to Task gives more control. We can monitor Tasks and manage them:
https://github.com/lsmolinski/MonitoredQueueBackgroundWorkItem
Sorry for my english.

Categories

Resources