Is awaiting methods from synchronous sources with await Task.Run(() => good practice? - c#

I have a method that has the async keyword with a task. This method returns a string that comes from JwtSecurityTokenHandler().WriteToken(t); The thing is none of the assignments in the body of the method are awaitable.I get the warning CS-1998. That says you shouldnt use async for synchronous methods which makes complete sense. But then it adds that you can use await Task.Run(() => { . So is it good practice to do this?
public async Task<object> GenerateMyUserJwtToken(string email, IdentityUser user)
//code that isnt awaitable
{
var u = await Task.Run(() =>
{
return new JwtSecurityTokenHandler().WriteToken(token);
});
return u;
}
edit: I did not ask what the error was I asked if it was a good idea to Implement await Task.Run(() on an async method signature that has no await assignments. I also asked that another async method is awaiting this in the another method here is the code
//awaiting method:
public async Task<object> LoginAsync(LoginDto model)
{
return await GenerateMyUserJwtToken(model.Email, appUser);
}
//controller:
[HttpPost("login")]
public async Task<object> Login([FromBody] LoginDto model)
{
var logMeIn = await new AuthUserService().LoginAsync(model);
return logMeIn; //returns token
}
My Question is is this async all the way or does the task.Run stop that process?

Using Task.Run just to make something sync is generally a bad practice but it cannot be stated generally.
If the sync method to execute may take for a long time, then it can be a solution. Please note that Task.Run will assign the task to a pool thread and it is not always desirable. It is a common misunderstanding that async methods always use or should use threads somewhere at the end of the async-await chain. However, async-await has nothing to do with threads, it is about asynchronicity (chaining deferred tasks) and creating threads is just one option to create awaitable tasks.
So what are the options?
The method to call is fast and never blocks the caller for long time (>100ms or so): do not use async at all. In this case Task<T>.FromResult(result) is a tempting solution but is highly discouraged because it is misleading for the caller. Use it only in unit tests or if you are forced to implement an async method of an interface you cannot change.
The method execution takes for a long time because it is CPU bound: now you can use a thread. But I typically would not use pool threads for long lasting tasks as it can cause nasty side effects if the thread pool is out of threads. Use await Task.Factory.StartNew(() => MyLongRunningTask(), cancellationToken, TaskCreationOptions.LongRunning); instead, which creates a brand new thread instead of bothering the pool.
The method execution takes for a long time because it is IO bound (eg. sending/receiving packets via a hardware): Use TaskCompletitionSource<T>, add a hook to the whatever completition event of the device (eg. OS hook or IRQ notification) and from that set the result of the completition source and return its task.

Related

C# Task.Delay(1).Wait() deadlocks but only if inside another Task [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.

Which is the proper way for async method returns task?

I am so confused with the following methods. Which one is the best and why? These are working fine.
public string GetString(int i)
{
return "Testing number " + i.ToString();
}
//async methods where I'm confused with
public Task<string> GetStringAsync(int i)
{
return Task.FromResult<string>(GetString(i));
}
//Or
public Task<string> GetStringAsync(int i)
{
Task<string> task = new Task<string>(() => GetString(i));
task.Start();
return task;
}
//Or
public Task<string> GetStringAsync(int i)
{
var tcs = new TaskCompletionSource<string>();
tcs.SetResult(GetString(i));
return tcs.Task;
}
The caller will be
Task<string> task = SomeClass.GetStringAsync(9);
Console.WriteLine(task.Result);
//Or
var result = await SomeClass.GetStringAsync(9);
Console.WriteLine(result);
Thank you so much.
I think you may not fully understand why anyone would want to use async. Async .Net allows the freeing up of threads that would normally be waiting on some external action to take place (network call or hard disk call). Normally windows uses I/O Completion Ports for these calls and has recently added async/await keywords to allow .Net access to native asynchronous calls. That being said there is a little overhead when using async as the runtime has to create a state-machine to keep track of a threads current state before assigning the await'd thread a new task.
Thus any async tasks that aren't using a I/O Completion Port are most likely doing more harm than good.
//async methods where I'm confused with
public Task<string> GetStringAsync(int i)
{
return Task.FromResult<string>(GetString(i));
}
Well let me correctly code this into an async method:
//async methods where I'm confused with
public async Task<string> GetStringAsync(int i)
{
return await Task.FromResult<string>(GetString(i));
}
Still bad, because there is no reason to use async; unless I'm mistaken about how Task.FromResult() works, this has additional overhead for no benefit.
I'm just going to rewrite them all as async and then give my understanding of what affect they have.
public async Task<string> GetStringAsync(int i)
{
Task<string> task = new Task<string>(() => GetString(i));
await task.Start();
return task;
}
It's extremely rare that you should be creating and starting your own tasks, it's not a good idea.
public Task<string> GetStringAsync(int i)
{
var tcs = new TaskCompletionSource<string>();
tcs.SetResult(GetString(i));
return tcs.Task;
}
The TaskCompletionSource was primarily designed to wrap current asynchronous into the async/await pattern. Since this isn't wrapping any type of asynchronous action there is no performance benefit.
public string GetString(int i)
{
return "Testing number " + i.ToString();
}
This is your best bet. Don't use async/await unless you actually need to.
Stephen Cleary has a great set of Posts that talk about Tasks and Async, I highly recommend you read through it before diving into Async in .Net.
Actually, none of the above are correct.
public Task<string> GetStringAsync(int i)
{
Task<string> task = new Task<string>(() => GetString(i));
task.Start();
return task;
}
should actually be:
public async Task<string> GetStringAsync(int i)
{
return await Task.Run(() => GetString(i));
}
Note, in particular, the use of the "async" keyword (which enables the use of the "await" keyword; "await" is the equivalent of "come back to me when I have a result for you," see the documentation for details of the state machine that this creates). The examples you provide reflect an older way of doing task parallelism that is no longer a best practice.
An important note at this point: make sure it's the case that GetString is a CPU-bound task. There are several kinds of async methods: ones that run asynchronously in the same thread (which are primarily used for IO-bound tasks), ones that run in the thread pool (which are used primarily for CPU-bound tasks), and ones that shouldn't be async in the first place (things that are neither CPU-bound or IO-bound).
My standard illustration of this fact is as follows: suppose you go a restaurant with 10 people. When the waiter comes by, the first person he asks for his order isn't ready; however, the other 9 people are. Thus, the waiter asks the other 9 people for their orders and then comes back to the original guy hoping he'll be ready to order by then. (It's definitely not the case that they'll get a second waiter to wait for the original guy to be ready to order and doing so probably wouldn't save much time anyway). That's how async/await works in many cases (the exception being that some of the Task Parallel library calls, like Thread.Run(...), actually are executing on other threads - in our illustration, bringing in a second waiter - so make sure you check the documentation for which is which).
Thus, when you're using async/await, make sure you know whether something is CPU-bound (and therefore appropriate for executing on a separate thread), IO-bound (and therefore appropriate for asynchronous execution in the same thread), or neither (and therefore pointless to make async in the first place).

Difference in task processing

Let's suppose that I Have two methods, like this...
public void MyMethod()
{
// do some stuff
}
public Task MyMethodAsync()
{
//run MyMethod asynchronously
}
What is the best form to execute it in async way?
Like this
public Task MyMethodAsync()
{
return Task.Run(() => MyMethod());
}
or like this?
public async Task MyMethodAsync()
{
await Task.Run(() => MyMethod());
}
You should read Stephen Cleary's tutorial on when -- and when not -- to use Task.Run.
Short answer: don't use Task.Run to create a fake async method. If your code isn't truly async, then let the caller decide if it should use a thread (or whatever) to call your code.
In the case of your first method, you may as well just have a task on a separate thread. It's not really async because you aren't clearly waiting for the thread to end to start a new process. If you called this it would continue before the task was complete.
public Task MyMethodAsync()
{
return Task.Run(() => MyMethod());
}
Looking at the second version. You are waiting for the task to complete so that you can do something after without holding up the current thread.
public async Task MyMethodAsync()
{
await Task.Run(() => MyMethod());
DoMoreWork();
//Do something following the completion of the task
//without binding up the calling thread, but actually complete it on that thread.
}
It's better to go the other way around. Build the inner task as async, and then let all the callers who can't use the async method use the async one internally and wait on it.
public void MyMethod()
{
MyMethodAsync().Wait();
}
public async Task MyMethodAsync()
{
// do some stuff
}
Both of your methods aren't truly making anything async. Async isn't about running something in the background, that's the realm of the Task library (or parallel extensions, or threading, etc). Async is about being able to re-use a single thread for multiple things when it has nothing better to do -- which makes thing more scalable. Making a pseudo-async method is just hiding the fact that you are using a NEW thread instead of reusing the same thread, which makes the system LESS scalable.
In order to do that, true async processes need to be written that way from the inside out. Everything (or at least the parts that are time consuming) need to rely on async methods that do that. For example, making a SOAP call where the thread is going to basically just sit idle while waiting for the call to return, or a database call, or file I/O. Async allows that thread to go do something else useful instead of just sitting idle.

HttpClient.PostAsync hanging Windows Phone 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.

When to return task over using async

I am abit confused when it comes to how a method should look like when dealing with async / task.
From my understanding, a method that just creates a new task doesnt need to be async since this would produce overhead as it wraps the hole thing in a new task.
So this:
async Task _doStuff()
{
await Task.Run(()=> _stuff());
}
Is better this way:
Task _doStuff()
{
return Task.Run(()=> _stuff());
}
However, it gets a bit more complicated, if there are some preconditionchecks
Which way is better then?
async Task _doStuff()
{
if(stuffWasDone)
return;
await Task.Run(()=> _stuff());
}
or
Task _doStuff()
{
if(stuffWasDone)
return Task.Run(()=> {}); // this could be a static-readonly in some helper like AsyncHelper.Empty(); as there is no FromResult for Task.
return Task.Run(()=> _stuff());
}
You dont have to use Task.Run in order to generate a Task. A Task is a promise.
If a Task doesn't need to execute, don't create one. Using Task.Run has the overhead of invoking an empty lambda on a threadpool thread, you don't need that. Simply returning should suffice.
You may also use Task.FromResult if no Task is actually needed:
Task DoStuffAsync()
{
if(stuffWasDone)
{
return Task.FromResult(0);
}
return Task.Run(() => _stuff());
}
If you don't want to re-generate the Task over again, you can simply put it in a local variable:
private static Task _emptyTask = Task.FromResult(0);
As for your first example of await vs return await, you cannot say one is "better" then the other, as they serve different purposes. The former will asynchronously wait for the Task to complete before returning while the latter will return a hot task to the caller. This will matter in regards of exception handling. More so, if you're not going to be consuming the result of the task afterwards, using await will incur in a redundant generation of a state machine.
As another side note, wrapping synchronous methods in asynchronous wrappers is bad practice. Let the end user explicitly call Task.Run instead, don't fool them with async behavior.

Categories