call method async inside Task.Run - asp.net-mvc

the code shown below is executed inside an asp.net mvc application
public async Task<string> GetCustomers1(){
return await getcustomer1Async();
}
public async Task<string> GetCustomers2(){
return await getcustomer2Async();
}
public async Task<JsonResult> Index(){
var result1 =Task.Run(()=>GetCustomers1());
var result2 =Task.Run(()=>GetCustomers2());
Task.WaitAll(result1,result2);
}
I am clear that task run will create two threads to execute methods GetCustomers1, GetCustomers2.
- my question is when the method GetCustomers1 and GetCustomers2 reach the line that has the word await, should the incomplete task be returned, where should the incomplete task be returned? Does the thread return to the thread pool?
-Task.WaitAll would you have the main thread busy until the other tasks finish running?
I know you shouldn't use tak.run if the method is asynchronous. But I want to know how the code works internally in such a scenario.

I am clear that task run will create two threads to execute methods GetCustomers1, GetCustomers2.
Task.Run doesn't create threads. It queues work to the thread pool.
my question is when the method GetCustomers1 and GetCustomers2 reach the line that has the word await, should the incomplete task be returned, where should the incomplete task be returned? Does the thread return to the thread pool?
Yes, the thread is returned to the thread pool. When the await is ready to resume execution, the "continuation" of that method is queued to the thread pool. Note that continuations may or may not run on the same thread; they can run on any thread pool thread.
Task.WaitAll would you have the main thread busy until the other tasks finish running?
Yes, that is what Task.WaitAll will do. It also blocks on asynchronous code, which is not a good idea. It's better to go async all the way.
I know you shouldn't use tak.run if the method is asynchronous.
Using Task.Run for asynchronous code is fine. But in the general case, you shouldn't use Task.Run on ASP.NET because it queues work to the thread pool instead of letting ASP.NET have full control of the thread pool. Instead, call the asynchronous code directly and use asynchronous code (Task.WhenAll) instead of blocking code (Task.WaitAll):
public async Task<string> GetCustomers1() {
return await getcustomer1Async();
}
public async Task<string> GetCustomers2(){
return await getcustomer2Async();
}
public async Task<JsonResult> Index(){
var result1 = GetCustomers1();
var result2 = GetCustomers2();
await Task.WhenAll(result1, result2);
}

Yes, at the await line the methods GetCustomers1 and GetCustomers2 will immediately return an incomplete task, assuming that the tasks returned from getcustomer1Async() and getcustomers2Async() are incomplete. The await keyword allows you to write code below the await line, that will run after the awaited task is completed. In your case there is no code below the await line, so you could just as well return directly the tasks without awaiting them:
public Task<string> GetCustomers1()
{
return getcustomer1Async();
}
Notice that not only the await keyword is gone, but the async as well.
As for the Index method, it should give you a compile-time warning for not having an await inside a method marked with the async keyword. You should probably modify it to something like this:
public async Task<JsonResult> Index()
{
var task1 = Task.Run(() => GetCustomers1());
var task2 = Task.Run(() => GetCustomers2());
string[] results = await Task.WhenAll(task1, task2);
//...use the results to create a JsonResult and return it
}
Finally keep in mind that it's common practice to add the suffix Async to the methods that return a Task. So the method GetCustomers1 should be renamed GetCustomers1Async, the Index should be renamed IndexAsync etc. You can read the relevant guidelines here.

Related

Confusion in Dart's async await

I have a confusion in understanding Dart's async/await functionality. Most tutorials use the following example:
Future<String> createOrderMessage() async {
var order = await fetchUserOrder();
return 'Your order is: $order';
}
Future<String> fetchUserOrder() =>
// Imagine that this function is
// more complex and slow.
Future.delayed(
const Duration(seconds: 2),
() => 'Large Latte',
);
Future<void> main() async {
print('Fetching user order...');
print(await createOrderMessage());
}
I understand that the fetchUserOrder function returns a Future. Anyone who calls this function will immediately get a Future object as a result but this Future object may not have the real result value at that time. It will be filled up in "future".
Now, the createOrderMessage function calls: await fetchUserOrder(); This means, the control will wait till fetchUserOrder() returns a completed/non-empty Future. Am I right here? Is this what await does?
If that is correct, it means, the createOrderMessage function is essentially synchronous now because it won't return until the Future returned by fetchUserOrder is filled. Thus, the order variable in this function is initialized with a completed Future. Then why does this function need the "async" keyword in its function declaration? What does it signify?
Second confusion is if Dart is single threaded, when and how exactly is an async function executed? If I invoke multiple method calls that return Futures like this without await:
...
Future<A> fa = getA();
Future<B> fb = getB();
Future<C> fa = getC();
...
Will the functions getA, getB, and getC be executed sequentially in the background or they will be executed "in parallel" somehow?
Now, the createOrderMessage function calls: await fetchUserOrder(); This means, the control will wait till fetchUserOrder() returns a completed/non-empty Future. Am I right here? Is this what await does?
Yes. the await keyword means you get the completed T instead of Future<T> in return. So:
var a = fetchUserOrder(); // Type of a: Future<String>
var b = await fetchUserOrder(); // Type of b: String
When you use await, you tell the code to await the completion of the process and get the actual result. But without await, the stream is in the future and is in process until you await it somewhere else.
why does this function need the "async" keyword in its function declaration?
It's a rule to specify long-running functions. So when a function awaits for a long running process to complete, the function itself is also a long-running process. Why? Because it's waiting for another one to complete.
Therefore, you need to specify async for that as well. When another function is calling this one, it also knows this one might be long-running.
In short, every awaitable function needs to be in an async function.
Second confusion is if Dart is single threaded, when and how exactly is an async function executed?
You're mixing the concept of parallelism with asynchronous. An async process does not have to be done in multi thread.
Async processes can be one one at time, but in a different order in compare to synchronous code.
Take a look at this article which explains asynchronous in a single thread.
Now, the createOrderMessage function calls: await fetchUserOrder(); This means, the control will wait till fetchUserOrder() returns a completed/non-empty Future. Am I right here? Is this what await does?
If that is correct, it means, the createOrderMessage function is essentially synchronous now because it won't return until the Future returned by fetchUserOrder is filled. Thus, the order variable in this function is initialized with a completed Future.
await allows asynchronous functions to have the appearance of synchronous functions by allowing asynchronous code to be structured very similarly to synchronous code. In your example, it's syntactic sugar for registering a Future.then() callback and immediately returning:
Future<String> createOrderMessage() {
var future = fetchUserOrder().then((order) {
return 'Your order is: $order';
});
return future;
}
await defers execution of the rest of that function; it does not wait and block execution of your entire thread. Your program will continue running its event loop, possibly allowing other asynchronous operations to make progress.
Will the functions getA, getB, and getC be executed sequentially in the background or they will be executed "in parallel" somehow?
As I mentioned in comments, it depends on how getA, getB, and getC are implemented. They could run in parallel, such as if they run in separate Dart isolates or in separate threads in the Dart VM/runtime.

Async-await in dart runs synchronously?

I am trying out the Future with async await for asynchronous programming.
The code i tested is a simple Future.
//order a new coffee perhaps!
Future<String> order(String newOrder){
final String Function() func = ()=> "${newOrder} is requested!";
final _order = Future.delayed(Duration(seconds: 5),func);
return _order;
}
When i run this code like a promise.
order("promised order")
.then((result) => print(result))
.catchError((err){
print(err.error);
});
This behaves like a asynchronous non-blocking code
However the same code when i run it with async/await behaves like a synchronous code and blocks all the other code, it waits 5 secs to run the next line.
void main(List<String> arguments) async {
final _myOrder = await order('Lattee mocha');
print(_myOrder);
//...all the other code waits for
}
So i thought async/await is same as futures, where non-blocking..
How come it blocks the other code execution ?
The whole point of the async/await pattern is to wait (hence await) until the Future completes and only then continue with this code execution.
Think of it as a way to not have endless .then() chains and much simplified error handling.
If you want to not wait, then you just leave out the await keyword. Obviously, if you don't (a)wait, you don't get the result.
You can still use classic .then() chains when it suits your purpose better in your program.
What people talk about when they say "non blocking" they mean that when the compiler sees the await keyword, it knows to keep the rest of the program, the event loops, animations etc running and not block the complete program.

How does Dart run asynchronous code without blocking?

How does Dart run asynchronous code without blocking?
For example:
void test(User user) async {
print('test');
String fullName = user.firstName + ' ' + user.lastName;
final result = await sendRequest(fullName);
print('${result}');
}
I understand that when Dart runs async function, it executes code before await and then wraps the remaining code into Future and puts it into Event Loop. But, how does that Future what we're awaiting for (await sendRequest(fullName)) not blocking running the other, synchronous code? We should wait for request for complete but it also requires some code to check that we've received or not received response. How does it not block other operations, like button clicks?
The function returns at the first await. It returns a future which will later be completed (which is then ignored because of the void return type). Everything else in the function happens in reaction to callbacks from other futures (or streams, if you use await for).
The async function here is basically rewritten into something like:
void test(User user) {
print('test');
String fullName = user.firstName + ' ' + user.lastName;
return sendRequest(fullName).then((final result) { // <-- Returns here, synchronously.
print('${result}'); // <-- Gets called by the future of `sendRequst(fullName)`.
});
}
This transformation is similar to a continuation-passing style transformation in the it takes the continuation (the control flow in the body of the function after the await) and makes it into a function.
(In reality, the transformation is more complicated because it needs to account for loops, try/catch/finally, and even break statements. Because of that, even a simple example like this one will likely be converted into something more complicated than absolutely necessary).

Does an async function requires the inner functions marked as async too?

Future<void> doIt() async {
// here are some operations which are not marked as async
// but still take some time
print ('done');
return;
}
Should the above function execute as async even though the inner operation are not marked as async if I run it like below?
await doIt();
print(next output);
Will the output be
next output
done
or
done
next output
Or, in other words, is there a way to execute regular function as async function?

Should I use Task.Wait()?

Should I use taskThatReturns.Wait() in code below or I can omit it since according to my understanding taskThatReturns.Result will do wait anyway.
Task<string> taskThatReturns = new Task<string>(MethodThatReturns);
taskThatReturns.Start();
taskThatReturns.Wait();
Console.WriteLine(taskThatReturns.Result);
The call of Wait() before accessing Result is unnecessary.
Examination of the reference code of Task and Task<TResult> shows that both the void Wait() method and the getter of the Result property eventually make their way into the method that does the actual waiting:
internal bool InternalWait(int millisecondsTimeout, CancellationToken cancellationToken)
Both code paths send identical parameter values to InternalWait - infinite wait and default cancellation token.
If you call Wait before accessing Result, the code path inside the getter leading to InternalWait would be skipped, because the task is known to be completed. However, the net result would remain the same in both cases.
Note: This answer intentionally ignores opportunities to optimize your code fragment.
async void DoTask() {
string task = await returnString();
Console.WriteLine(task);
}
Task<string> returnString() {
// you code here
}
You can use async method to await Task execution
To answer the actual question. You either need to wait to get the results, or you need to do as Panagiotis Kanavos suggested, and await a task. You're overcomplicating threading, a common issue with all the bad examples out there.
If you still want to use Task better approach is:
var result = taskThatReturns.GetAwaiter().GetResult();

Resources