What is the difference between these two asynchronous methods? - c#

What's difference between this two asynchronous methods? If didn't, In which situation this two kind of methods can was different?
Thanks.
public async Task<int> MyMethod1Async()
{
return 1;
}
public async Task<int> MyMethod2Async()
{
return await new Task<int>(() => 1);
}

Taking a look at the two methods:
public async Task<int> MyMethod1Async()
{
return 1;
}
This will run synchronously because there are no "await" operators in it - it just returns 1, so it's no different than if you had just done the following:
public int MyMethod1()
{
return 1;
}
The following method is probably a better illustration of the difference between different "types" of async:
public async Task<string> MyMethod1Async()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("SomeBaseAddress");
// This will return control to the method's caller until this gets a result from the server
HttpResponseMessage message = await client.GetAsync("SomeURI");
// The same as above - returns control to the method's caller until this is done
string content = await message.Content.ReadAsStringAsync();
return content;
}
}
Code like this won't necessarily spawn extra threads (unless that's how Microsoft happened to have implemented those particular library calls). Either way, await/async does not require the creation of additional threads; it can run asynchronously on the same thread.
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).
The next item you list won't work because you just create the task, you don't actually do anything with it:
public async Task<int> MyMethod2Async()
{
return await new Task<int>(() => 1);
}
I'm assuming that you actually intended to do something like the following:
public async Task<int> MyMethod2Async()
{
return await Task.Run<int>(() => 1);
}
This will run the lambda expression in the thread pool, return control to MyMethod2Async's caller until the lambda expression has a result, and then return the value from the lambda expression once it does have a result.
To summarize, the difference is whether you're running asynchronously on the same thread (equivalent to the first guy at your table telling the waiter to come back to him after everyone else has ordered) or if you're running the task on a separate thread.
At risk of oversimplifying things a lot, CPU-bound tasks should generally be run asynchronously on a background thread. However, IO-bound tasks (or other cases where the holdup is mostly just waiting for some kind of result from an external system) can often be run asynchronously on the same thread; there won't necessarily be much of a performance improvement from putting it on a background thread vs. doing it asynchronously on the same thread.

The first method returns an already completed task with a Result of 1.
The second method returns a Task<int> that will never complete.

Related

Difference Await and ContinueWith

I've read some threads regards the difference between await and ContinueWith. But no one has answer me completely.
I've got a DataAccess Layer that insert records in a database using Dapper.
The InsertAsync method is:
public Task<int> InsertAsync(TEntity entity)
{
return Connection.InsertAsync(entity, Transaction).ContinueWith(r => Convert.ToInt32(r.Result));
}
I don't use async and await because in my head who will use this method will waiting for the result.
Is correct?
I don't use async and await because in my head who will use this method will waiting for the result. Is correct?
That is not correct. While the await keyword does indeed wait for Connection.InsertAsync to complete before it calls Convert.ToInt32, the moment it starts waiting for Connection.InsertAsync it releases control back to its caller.
In other words, the caller will not be stuck waiting for Connection.InsertAsync to finish. The caller will be told "this will take a while, feel free to do something else", so it can continue.
Now, if the caller themselves was explicitly told to await the InsertAsync(TEntity) method on the same line that you call the method, then it will wait and it won't do anything else (except release control back to its caller), but that's because it was explicitly instructed to wait at that point.
To explain in code:
// I will wait for this result
var myInt = await Connection.InsertAsync(myEntity);
// I will not do this until I receive myInt
var sum = 1 + 1;
var anotherSum = 2 + 2;
var andAnotherSum = 3 + 3;
Without the await, the caller will just move on to the next command and do its work, all the way up to the point where it is finally told that it must await the task returned from InsertAsync(TEntity).
To explain in code:
// I will ask for this result but not wait for it
var myIntTask = Connection.InsertAsync(myEntity);
// I will keep myself busy doing this work
var sum = 1 + 1;
var anotherSum = 2 + 2;
var andAnotherSum = 3 + 3;
// My work is done. I hope the task is already done too.
// If not, I will have to wait for it because I can't put it off any longer.
var myInt = await myIntTask;
I've read some threads regards the difference between await and ContinueWith.
Functionally speaking, there is no difference between the two. However, the ContinueWith syntax has recently fallen out of popular favor, and the await syntax is much more favored because it reduces nesting and improves readability.
In terms of waiting, the behavior is exactly the same.
Personally, I suspect that ContinueWith is a leftover artifact from initially trying to design async methods the same way that promises in JS work, but this is just a suspicion.
That should be fine. However, there is a recommendation to always pass a taskscheduler to Continue with, to avoid any ambiguity of what context the continuation will run in, even if it does not matter in this particular case.
I would prefer the version
public async Task<int> InsertAsync(TEntity entity)
{
var r = await Connection.InsertAsync(entity, Transaction);
return Convert.ToInt32(r);
}
I consider this easier to read, and it will always execute the continuation on the same context as the caller. Behind the scenes it will produce very similar code to your example.
You should definitely prefer async/await over the ContinueWith method.
public async Task<int> InsertAsync(TEntity entity)
{
var result = await Connection.InsertAsync(entity, Transaction);
return Convert.ToInt32(result);
}
The primitive ContinueWith method has many hidden gotchas. Exceptions thrown synchronously, exceptions wrapped in AggregateExceptions, TaskScheduler.Current ambiguity, SynchronizationContext not captured, nested Task<Task>s not properly unwrapped, will all come and bite you at one point or another, if you get in the habit of following the ContinueWith route.

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.

WCF Service: Call first function, return from it, then call second function to work in background

I am writing a WCF Service in which I have to call two functions to update the database but I want to return after first table update so that client should not wait longer and then second table will update in background.
The thing I want to do is like this:
public bool myMainFunction(){
bool result = updateTable1();
return result;
updateTable2();
}
How can I achieve this?
Thanks
Try this
using System.Threading.Tasks;
public bool MyMainFunction()
{
bool result = UpdateTable1();
Task.Run(() => UpdateTable2());
return result;
}
Task.Run(Action action)
From : https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
Queues the specified work to run on the thread pool and returns a Task object that represents that work.
Basically, Task.Run queues your item on the threadpool - which allows it to run asynchronously. Usually you would pair this with the task's Wait or Result methods to block the calling thread until the task has finished - for example :
using System.Threading.Tasks;
public bool MyMainFunction()
{
Task<bool> task = Task.Run(() => UpdateTable1());
Task.Run(() => UpdateTable2());
return task.Result;
}
In the previous example - both methods are now queued on the Threadpool - which means they can executed in parallel. (In the first example - UpdateTable1 had to finish before UpdateTable2 began - but we fired and forgot about UpdateTable2 - so it was inconsequential). The new example now allows UpdateTable2 to begin executing before UpdateTable1 has finished. However - we would now have a problem - as we need to wait for the result of UpdateTable1 to return the bool value required.
When you call either, task.Wait() or task.Result, your method basically pauses until the task has finished - in this case, it waits until table1 has updated.
Now - you'll notice we don't have a variable to store the state of UpdateTable2's tasks - this is because you don't care about the result. Since there is no variable stored we don't ever block the calling thread to view the result - which means that you've effectively got a "Fire and Forget" method.
Hopefully this helps clear it up a bit - but if not there are plenty of resources out there to help, look into Asynchronous and Parallel programming as there will be people out there who can explain more clearly than I.
The following has been useful to me :
mcsd-certification-toolkit-exam-70-483
I have also converted your method names from Camel Case to Pascal Case, as this is standard practice.

From the point of view of the caller, how is calling an asynchronous method any different than calling a synchronous method?

What I don't understand is the following snippet from MSDN:
Note that the method is now marked with the new async keyword; this is
simply an indicator to the compiler that lets it know that in the
context of this method, the keyword await is to be treated as a point
where the workflow returns control to its caller and picks up again
when the associated task is finished.
How is that any different than how non-async methods work?
If I do
int x;
x = SomeNormalFunctionThatReturnsAnInt();
Console.WriteLine(x);
or
int x;
Task<int> task = SomeAsyncFunctionThatReturnsAnInt();
x = await task;
Console.WriteLine(x);
then from the perspective of the caller, the order of execution is the exact same: an int named x is defined, a function that returns an int is run, and when that funcion is done running, its return value is set to x, which is then written to the console.
from the perspective of the caller, the order of execution is the exact same
Yes and no.
If you await all tasks as soon as they are returned to you, then yes, that method in isolation is seeing the same "order of execution". This is actually the entire point of async/await - it allows writing most asynchronous code in a way that is very natural and similar to equivalent synchronous code.
However, the caller must be aware that it has to be asynchronous. That is, the caller generally uses await, which means that it must be async. There are some added twists that come in with asynchronous code. One example: if this is executed on a UI thread, then synchronous code knows that nothing else can execute on the UI thread between SomeNormalFunctionThatReturnsAnInt and Console.WriteLine; however, asynchronous code uses await, so it must accept that anything else can execute on the UI thread between SomeAsyncFunctionThatReturnsAnInt and Console.WriteLine. So, looking at it from that context, it's not the exact same; asynchronous methods may have their "order of execution" paused while other code runs.
If you weren't waiting the result of the function x could be not initialized. But here you wait for it so there is no difference.
you need to have some read on the async and sync to see what happens in performance level ,
in your example the result is not different as you are saying the method to wait in line of await but lets have a look at the following code snippet
class Program {
private static string result;
static void Main() {
SaySomething();
Console.WriteLine(result);
}
static async Task<string> SaySomething() {
await Task.Delay(5);
result = "Hello world!";
return “Something”;
}
}
can you try to calculate the output, the result is nothing, why ?
with the await we let the main task continue as we wait 5 milliseconds before returning result, have a look at
https://msdn.microsoft.com/en-gb/library/mt674882.aspx

Write your own async method

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

Categories