dart flutter - Why is this await unnecessary? - dart

my linter is telling me this await is unnecessary:
Unnecessary await keyword in return.
I thought if you're calling a function inside an async function and you want to get/return the value, rather than the future you had to use await to designate you want the value, not the future.
Am I missing something here?

As the documentation for that recommendation points out, you can take off the async and just return the Future, rather than using await:
Future<Dictionary> get _localDir => getApplicationDocumentsDirectory();
This is called "eliding async/await". Stephen Cleary wrote an article about it (written for C#, but largely applicable for any language that uses async and await), which you may find helpful: Eliding Async and Await
In short, it's more efficient to do this in situations when you can:
By not including these keywords, the compiler can skip generating the async state machine. This means that there are fewer compiler-generated types in your assembly, less pressure on the garbage collector, and fewer CPU instructions to execute.

Related

Why do you use async if you don't promote it to the controller?

I'm trying to figure out how to use async/await in C# in my Asp.Net MVC.
The main point seems to be that it helps asp.net for releasing threads from the worker pool when you are doing IO (so they can process other stuff). For doing so you have to promote the async/await modifier from the method doing the IO call up to the controller action (you better have just a few layers).
Is there any point in using this feature without promoting the async/await up to my controller ? (by adding Task.Wait after a call to an Async method for instance).
The answer is "yes", but using Task.Wait() in an action is not a good idea because it can lead to a deadlock situation.
Consider the following from the guide, Async/Await Best Practice by Stephen Cleary:
Figure 3 A Common Deadlock Problem When Blocking on Async Code
public static class DeadlockDemo
{
private static async Task DelayAsync()
{
await Task.Delay(1000);
}
// This method causes a deadlock when called in a GUI or ASP.NET context.
public static void Test()
{
// Start the delay.
var delayTask = DelayAsync();
// Wait for the delay to complete.
delayTask.Wait();
}
}
However, if you add ConfigureAwait(false) to DelayAsync() like this:
await Task.Delay(1000).ConfigureAwait(false)
then you can avoid deadlocks, as explained in the article:
Aside from performance, ConfigureAwait has another important aspect: It can avoid deadlocks. Consider Figure 3 again; if you add “ConfigureAwait(false)” to the line of code in DelayAsync, then the deadlock is avoided. This time, when the await completes, it attempts to execute the remainder of the async method within the thread pool context. The method is able to complete, which completes its returned task, and there’s no deadlock. This technique is particularly useful if you need to gradually convert an application from synchronous to asynchronous.
Do not use Task.Wait as it can deadlock or produce an AggregateException. If you need to do this then you should use Task.WhenAll which is non-blocking.
Generally though, it is safest to use async code end-to-end. The benefit of using async away through the entire stack is that your code will be easier to debug and error handling much simpler.
So yes, if you are going to use async/await - include it in your controller and avoid using blocking code like Task.Wait.

Why does an async method needs to return a future?

I am trying to wrap my head around this. I have to be understanding incorrectly.
Example:
Future A() { ..}
Future B() async{
await A();
print "123";
}
Why does B need to return a Future?
Doesn't await make B() synchronous? i.e., It waits for A to completely finish and then executes the print statement.
Then, What is the necessity for B to return a Future?
async and await don't make async execution sync. There is no way to do that.
All async and await does is to make async code look more like sync code. It is just syntactic sugar. Everything that can be done with async and await can be done without it as well.
Instead of deeply nested .then(...then(...then(...).catchError())).catchError(...) distinct statements, for loops, try, catch, finally can be used which makes code easier to write, read and reason about.
In Dart language an async modifier allows to use an extended syntax in asynchronous functions (and, of course, asynchronous functions which in most cases cannot return result immediately until they not completed, they return a wrapper of the future result which called in Dart a Future).
Using extended syntax means a possibility to write asynchronous operations in the same manner if you wrote a synchronous operations.
In order to be able in a single function use both synchronous and asynchronous operations the extended syntax allows to use operator await.
With operator await the asynchronous operations will look like they are synchronous operations because an operator await perform a work which can be called asynchronously wait until the operation will not completed.

Does let!/do! always run the async object in a new thread?

From the wikibook on F# there is a small section where it says:
What does let! do?#
let! runs an async<'a> object on its own thread, then it immediately
releases the current thread back to the threadpool. When let! returns,
execution of the workflow will continue on the new thread, which may
or may not be the same thread that the workflow started out on.
I have not found anywhere else in books or on the web where this fact (highlighted in bold) is stated.
Is this true for all let!/do! regardless of what the async object contains (e.g. Thread.Sleep()) and how it is started (e.g. Async.Start)?
Looking in the F# source code on github, I wasn't able to find the place where a call to bind executes on a new (TP) thread. Where in the code is the magic happening?
Which part of that statement do you find surprising? That parts of a single async can execute on different threadpool threads, or that a threadpool thread is necessarily being released and obtained on each bind?
If it's the latter, then I agree - it sounds wrong. Looking at the code, there are only a few places where a new work item is being queued on the threadpool (namely, the few Async module functions that use queueAsync internally), and Async.SwitchToNewThread spawns a non-threadpool thread and runs the continuation there. A bind alone doesn't seem to be enough to switch threads.
The spirit of the statement however seems to be about the former - no guarantees are made that parts of an async block will run on the same thread. The exact thread that you run on should be treated as an implementation detail, and when you yield control and await some result, you can be pretty sure that you'll land on a different thread at least some of the time.
No. An async operations might execute synchronously on the current thread, or it might wind up completing on a different thread. It depends entirely on how the async API in question is implemented.
See Do the new C# 5.0 'async' and 'await' keywords use multiple cores? for a decent explanation. The implementation details of F# and C# async are different, but the overall principles are the same.
The builder that implements the F# async computation expression is here.

Replacement for Future.transform?

I'm going over some older Dart code, addressing breaking changes with the latest Dart SDK. This one I can't figure out:
Future<DateTime> get lastsave =>
client.lastsave.transform((int unixTs) =>
new DateTime.fromMillisecondsSinceEpoch(unixTs * 1000, isUtc:true));
=>
The method 'transform' is not defined for the class 'Future<List<int>>'
From what I understand, the purpose of Future.transform() was to apply a synchronous transformation (see e.g. this discussion thread). I.e. convert the async call to a sync call and return the value.
Has Future.transform been replaced with something else?
Must have been quite a while since that code was updated ;)
Just replace transform with then and it should work.
From https://groups.google.com/a/dartlang.org/forum/#!topic/misc/Boch2XH9Tmk
We have also improved the Future class, and made it simpler to use. One simple “then” methods lets you apply asynchronous or synchronous functions to the result of a future, merging the three methods “chain”, “transform” and “then”. Streams and Futures should make asynchronous Dart programs easier to write and read, and should reduce some types of programming errors.

Dart ways of handling Futures

I saw a Dart screencast about Futures and how to handle them. It said there are two ways of handling some Futures that mixed with sync code. This is the example code:
import 'dart:async';
Map sanitizeParams(Map p) {/*.....*/}
Future sendToServer(Map p) {/*.....*/}
Future sendParams(Map params) => sendToServer(sanitizeParams(params));
Above is the less preferred way, and here is the code that is better (according to the one who made the screencast) :
import 'dart:async';
Map sanitizeParams(Map p) {/*.....*/}
Future sendToServer(Map p) {/*.....*/}
Future sendParams(Map params) =>
new Future.value(params)
.then(sanitizeParams)
.then(sendToServer);
Why is the second one preferred?
First reason is readability: sanitizeParams needs to happen before sendToServer but it reads in different order, which is preferably avoided when working with futures.
The more important reason is that if sanitizeParams throws an exception then sendParams won't return a future but throw instead, and this makes it harder to compose it with other futures. The second example avoids this by first making the arguments available as Future (Future.value) and then chaining other functions on that.
IIRC, this is explained in the screencast.

Resources