Why Future works after the main function was done? - asynchronous

In the example on dart.dev the Future prints the message after the main function was done.
Why might the Future work after the main function was done? At first glance, after the completion of the main function, the entire work of the program is expected to be completed (and the Future must be cancelled).
The example code:
Future<void> fetchUserOrder() {
// Imagine that this function is fetching user info from another service or database.
return Future.delayed(Duration(seconds: 2), () => print('Large Latte'));
}
void main() {
fetchUserOrder();
print('Fetching user order...');
}
The program prints
Fetching user order...
Large Latte
I've expected just the following
Fetching user order...

This has to do with the nature of futures and asynchronous programming. Behind the scenes, Dart manages something called the asynchronous queue. When you initiate a future (either manually like you did with Future.delayed or implicitly by calling a method marked async, that function's execution goes into the queue whenever its execution gets deferred. Every cycle when Dart's main thread is idle, it checks the futures in the queue to see if any of them are no longer blocked, and if so, it resumes their execution.
A Dart program will not terminate while futures are in the queue. It will wait for all of them to either complete or error out.

Related

How to call a async method from synchronous method?

I'm trying to call an asynchronous method from a synchronous method like below:
1. public List<Words> Get(string code)
{
Task<List<Words>> taskWords = GetWordsAsync(code);
var result = taskWords.Result;
return result;
}
private async Task<List<Words>> GetWordsAsync(string code)
{
var result = await codeService.GetWordsByCodeAsync(code);
return result;
}
But this lead to a deadlock, await is not getting the results from the method - GetWordsByCodeAsync
I've done a bit of research and came to know that if we are calling an async method from synchronous method we should use Task.Run
When I changed the code like below, it worked:
2. public List<Words> Get(string code)
{
Task<List<Words>> taskWords = Task.Run<List<Words>>(async () => await GetWordsAsync(code);
var result = taskWords.Result;
return result;
}
private async Task<List<Words>> GetWordsAsync(string code)
{
var result = await codeService.GetWordsByCodeAsync(code);
return result;
}
But I didn't get the context, why it caused a deadlock for 1st way and 2nd one worked fine.
I'd like to know:
What's the difference between two ways?
Is second one the correct way to call async method from synchronous method?
Will using the second method also causes a deadlock at some point of time if the result is large? or is it fail proof(safe) method to use?
Also, please suggest any best practices to better do it as I have to do 5 async calls from a synchronous method - just like taskWords, I have taskSentences etc.,
Note: I don't want to change everything to async. I want to call async method from synchronous method.
I don't want to change everything to async. I want to call async method from synchronous method.
From a technical standpoint, this doesn't make sense. Asynchronous means it doesn't block the calling thread; synchronous means it does. So you understand that if you block on asynchronous code, then it's no longer truly asynchronous? The only benefit to asynchronous code is that it doesn't block the calling thread, so if you block on the asynchronous code, you're removing all the benefit of asynchrony in the first place.
The only good answer is to go async all the way. There are some rare scenarios where that's not possible, though.
What's the difference between two ways?
The first one executes the asynchronous code directly and then blocks the calling thread, waiting for it to finish. You're running into a deadlock because the asynchronous code is attempting to resume on the calling context (which await does by default), and presumably you're running this code on a UI thread or in an ASP.NET Classic request context, which only allow one thread in the context at a time. There's already a thread in the context (the one blocking, waiting for the task to finish), so the async method cannot resume and actually finish.
The second one executes the asynchronous code on a thread pool thread and then blocks the calling thread, waiting for it to finish. There is no deadlock here because the asynchronous code resumes on its calling context, which is a thread pool context, so it just continues executing on any available thread pool thread.
Is second one the correct way to call async method from synchronous method?
There is no "correct" way to do this. There are a variety of hacks, each of which has different drawbacks, and none of which work in every situation.
Will using the second method also causes a deadlock at some point of time if the result is large? or is it fail proof(safe) method to use?
It will not deadlock. What it does, though, is execute GetWordsAsync on a thread pool thread. As long as GetWordsAsync can be run on a thread pool thread, then it will work.
Also, please suggest any best practices to better do it
I have written an article on the subject. In your case, if GetWordsAsync is safe to call on a thread pool thread, then the "blocking thread pool hack" is acceptable.
Note that this is not the best solution; the best solution is to go async all the way. But the blocking thread pool hack is an acceptable hack if you must call asynchronous code from synchronous code (again, it's "acceptable" only if GetWordsAsync is safe to call on a thread pool thread).
I would recommend using GetAwaiter().GetResult() rather than Result, in order to avoid the AggregateException wrapper on error. Also, the explicit type arguments are unnecessary, and you can elide async/await in this case:
var taskWords = Task.Run(() => GetWordsAsync(code));
return taskWords.GetAwaiter().GetResult();

How to wait for a Dart Future to complete, synchronously

Say, I have an async function that I want to call in a synchronous function. For example:
Future<int> foo() async {
// do something
return 109;
}
int bar() {
var r = wait_for_future(foo());
return r;
}
What I'm looking for is a possible implementation for wait_for_future. Can this even be done in Dart?
There is a provisional dart:cli – waitFor which allows one to synchronously wait for an async method.
This is only available on the Dart VM, though.
No, Dart is single-threaded, and it is not possible to block the main thread waiting for an asynchronous task:
Once a Dart function starts executing, it continues executing until it exits. In other words, Dart functions can’t be interrupted by other Dart code.
That means that there is no way to pause and wait for other Dart code to execute.

Resume execution at arbitrary positions inside a callback function

I am using Pin for dynamic analysis.
In my dynamic analysis task on 64-bit x86 binary code, I would like to resume the execution at arbitrary program positions (e.g., the second instruction of current executed function) after I fix certain memory access error inside the signal handling callbacks.
It would be something like this:
BOOL catchSignalSEGV(THREADID tid, INT32 sig, CONTEXT *ctx, BOOL hasHandler, const EXCEPTION_INFO *pExceptInfo, VOID *v)
{
// I will first fix the memory access error according to certain rules.
fix();
// then I would like to resume the execution at an arbitrary position, say, at the beginning of current monitored function
set_reg(rip, 0x123456); // set the rip register
PIN_ExecuteAt(ctx); // resume the execution
return false;
}
However, I got this exception: E: PIN_ExecuteAt() cannot be called from a callback.
I know I can resume the execution at "current instruction" by return false at the end of the signal handling function, but basically can I resume at arbitrary positions?
Am I clear? Thank you for your help!
The documentation is clear on this:
A tool can call this API to abandon the current analysis function and resume execution of the calling thread at a new application register state. Note that this API does not return back to the caller's analysis function.
This API can be called from an analysis function or a replacement routine, but not from a callback.
The signal handler is considered a callback. You can only use PIN_ExecuteAt in an analysis function or a replacement routine.
One thing you may try to do is to save the context you are interested in and allow the application to resume, ensuring that the next instruction to be executed has an analysis callback attached. You may be able to use if-then instrumentation to improve performance. Then you can call ExecuteAt from that analysis routine.

Windows Phone 8 SQLite async operations hanging indefinitely

I have a Windows Phone 8 app that utilizes SQLite.
I have a problem where some async SQLite operations hang indefinitely (presumably because they are awaited?)
Here is one such operation:
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("myDatabase");
var query = conn.Table<MyTable>().Where(x => x.Name == "name");
var result = await query.ToListAsync();
foreach (var item in result)
{
// breakpoint in the code here is never reached
}
This is in an async method which returns a Task< string>
This method is called early from the main page code. The main page never actually builds, as the app is hanging on this method (the screen just says "Loading..." indefinitely until I stop)
I'm guessing that further up your call stack (e.g., in your main page code), you are calling Result on a Task<T>. This will deadlock your program. I explain this in detail in my Best Practices in Asynchronous Programming article and my Don't Block on Async Code blog post.
To summarize: when you await an uncompleted Task, by default the current context is captured and used to restore the remainder of the async method after the Task completes. In your case, the captured context is a UI context, which only runs on a specified thread (the UI thread).
So, your main page code calls your async method which awaits the ToListAsync operation (capturing the UI context). Your async code returns an uncompleted Task to your main page code which calls Result on it. Result will (synchronously) block until the Task completes. When the ToListAsync operation completes, it attempts to execute the rest of your async method within the captured (UI) context. But the UI thread is busy; it's blocked waiting for that Task to complete. Thus, deadlock.

async CTP: I am doing something wrong, the GUI is blocked

I am making some probes with async CTP but I don't get a good result, because the GUI is blocked.
I have an WPF application with a button and a textBox for a log. Then I have this code:
private async void btnAsync01_Click(object sender, RoutedEventArgs e)
{
UpdateTxtLog("Enter in Button Async01: " + System.DateTime.Now);
await metodo01Async();
UpdateTxtLog("Exit button Async01: " + System.DateTime.Now);
}
private async Task slowMethodAsync()
{
UpdateTxtLog("Enter in slowMethod: " + System.DateTime.Now);
Thread.Sleep(5000);
UpdateTxtLog("Exit slowMethod: " + System.DateTime.Now);
}
If am not wrong, set a method with "sync" (click event in this case), it let the method use the await, to return the point to execution to the method which call the actual method, then the execution return to the GUI.
So in the GUI,I click the button, then in the click event await to the slowMethod, how I use await with the slowMethod the control should be returned to the GUI, and then the GUI should not be blocked. However, the GUI is blocked and the txtLog not show any information until slowMethod finish.
Is this because slowMethod is executed in the same thread than the GUI? If I am wrong, with async normally use the same thread than the method which call the await method, but I think that the reason of the async avoid this.
How can I simulate an slowMethod without thread.Sleep? Perhaps this is the problem, because in slowMethod I sleep the thread, and the thread of slowMethod is the same than the GUI.
This makes me think that is always recommended execute in other thread the code of the async methods? If this is correct, which is the sense to use async if also I need to use task for not blocking the main thread?
When to use async and when to use tasks?
For this probes, I am following the examples in this web: http://www.codeproject.com/Articles/127291/C-5-0-vNext-New-Asynchronous-Pattern
In this example, it's used client.DownloadStringTaskAsync as slowMethod, but in my case, instead of using a WebClient, I use a dummy method, with a sleep to simulate a slowMethod. I think that is the unique difference.
Thanks.
Daimroc.
Simulate waits using await TaskEx.Delay(5000), which executes an asynchronous sleep/delay.
You may also want to read up some more on async/await. There are several good Channel9 videos; Stephen Toub, Eric Lippert, and many other Microsoft bloggers have excellent overviews. Jon Skeet's "eduasync" blog series is also good for really going deep. I've written up an async intro on my own blog, as have many others.
Here's how async and await really work, in a nutshell:
The async keyword only enables the await keyword. That is all. It does not run the method on a background thread.
await only acts asynchronously if its "awaiter" is not completed.
So in your case, btnAsync01_Click and slowMethodAsync both run on the UI thread. slowMethodAsync will run synchronously (executing Thread.Sleep), and then return to btnAsync01_Click, which awaits the already-completed task. Since the task is already completed, btnAsync01_Click just continues executing without yielding to the UI message loop.
If you replace Thread.Sleep with await TaskEx.Delay, then btnAsync01_Click will start running on the UI thread, and will call slowMethodAsync (also running on the UI thread). When slowMethodAsync awaits the delay (which is not completed), it will return an incomplete task to btnAsync01_Click. btnAsync01_Click will await that task (which is not completed), and will return to the UI loop.
When the delay expires, it will complete, and slowMethodAsync will resume (on the UI thread). When slowMethodAsync completes, its returned task will complete, and btnAsync01_Click will resume (on the UI thread).

Resources