Async and await keywords in metro apps? - microsoft-metro

i am new to metro application development, i request you to help me understand the usage of async and await key words ,
As per my knowledge i understood that we async and await both simultaneously.
But if one method / function is mention as async :-
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
Uri inputUri = new Uri("http://examplewebservices");
try
{
string result = await httpClient.GetStringAsync(inputUri);
///
i have to do some operations on this string result here
///
}
catch (Exception ex)
{
}
}
1)what happens will a separate thread is created ?, and every thing inside that runs asynchronously ?
2)What will await keyword do here ?
3)if it is asynchronous , there is place in the code where i need to perform some operations on string result , if that is not completed it would show a error right ?
Please guide me out.
Thanks in Advance.

Please read my async/await intro.
1)what happens will a separate thread is created ?, and every thing inside that runs asynchronously ?
No. async methods are synchronous until they await an operation that isn't completed.
2)What will await keyword do here ?
It will asynchronously wait until the operation completes.
In this case, it will return back to the message loop and schedule the remainder of the method to run (on the UI thread) after the download completes.
3)if it is asynchronous , there is place in the code where i need to perform some operations on string result , if that is not completed it would show a error right ?
No. Because of the await, the rest of the method won't run until the download is complete.

Related

Making parallel and concurrent SignalR requests in flutter using bloc

With latest flutter bloc version , the events are processed concurrently.
here's is the scenario.
How to make concurrent signal R requests and show the result of all the requests for each millisecond until certain condition.
Here's what I have done.
Able to do single signal R request and get the result with bloc.
Also able to do multiple Signal R request once the previous request has been done processing.
What I need
To make concurrent or parallel signal r request using bloc while already a signalR request is under processing.
The sample code of the bloc's event
on<eventName>(
(event, emit) async {
for (final element in event.files) {
await establishSignalRConnection(uploadChannelId, element.name);
final DocumentUpload uploadAttachment =
await _Repository.upload();
emit(uploadedState(
emittedStateProperty
));
}
},
);
Thanks in Advance.
You could do it like this:
on<eventName>(
(event, emit) async {
const results = await Future.wait(
event.files.map((element) {
await establishSignalRConnection(uploadChannelId, element.name);
return await _Repository.upload();
});
// results now is a list of DocumentUploads, after all of them finished in parallel
emit(uploadedState(emittedStateProperty));
}
);
Please note that opening that many connections and sending one file over each is probably slower than having a signalR endpoint that just accepts multiple files. So if you can change the backend, that might be the better way, performance wise.

async/await - calling an async API from a syncronous method using dart [duplicate]

I'm on the way to evaluate Dart for a German company by porting various Java programs to Dart and compare and analyze the results. In the browser Dart wins hands down. For server software performance seemed to be a serious isssue (see this question of me) but that got mostly defused.
Now I'm in the area of porting some "simple" command-line tools where I did not expect any serious problems at all but there is at least one. Some of the tools do make HTTP requests to collect some data and the stand-alone Dart virtual machine only supports them in an asynchronous fashion. Looking through all I could find it does not seem to be possible to use any asynchronous call in a mostly synchronous software.
I understand that I could restructure the available synchronous software into an asynchronous one. But this would transform a well-designed piece of software into something less readable and more difficult to debug and maintain. For some software pieces this just does not make sense.
My question: Is there an (overlooked by me) way to embed an asynchronous call into a synchronously called method?
I imagine that it would not be to difficult to provide a system call, usable only from within the main thread, which just transfers the execution to the whole list of queued asynchronous function calls (without having to end the main thread first) and as soon as the last one got executed returns and continues the main thread.
Something which might look like this:
var synchFunction() {
var result;
asyncFunction().then(() { result = ...; });
resync(); // the system call to move to and wait out all async execution
return result;
}
Having such a method would simplify the lib APIs as well. Most "sync" calls could be removed because the re-synchronisation call would do the job. It seems to be such a logical idea that I still think it somehow exists and I have missed it. Or is there a serious reason why that would not work?
After thinking about the received answer from lm (see below) for two days I still do not understand why the encapsulation of an asynchronous Dart call into a synchronous one should not be possible. It is done in the "normal" synchronous programing world all the time. Usually you can wait for a resynchronization by either getting a "Done" from the asynchronous routine or if something fails continue after a timeout.
With that in mind my first proposal could be enhanced like that:
var synchFunction() {
var result;
asyncFunction()
.then(() { result = ...; })
.whenComplete(() { continueResync() }); // the "Done" message
resync(timeout); // waiting with a timeout as maximum limit
// Either we arrive here with the [result] filled in or a with a [TimeoutException].
return result;
}
The resync() does the same that would normally happen after ending the main method of an isolate, it starts executing the queued asynchronous functions (or waits for events to make them executable). As soon as it encounters a continueResync() call a flag is set which stops this asynchronous execution and resync() returns to the main thread. If no continueResync() call is encountered during the given timeout period it too aborts the asynchronous execution and leaves resync() with a TimeoutException.
For some groups of software which benefit from straight synchronous programing (not the client software and not the server software) such a feature would solve lots of problems for the programer who has to deal with asynchrounous-only libraries.
I believe that I have also found a solution for the main argument in lm's argumentation below. Therefore my question still stands with respect to this "enhanced" solution which I proposed: Is there anything which really makes it impossible to implement that in Dart?
The only time that you can wrap an async method in a synchronous one is when you don't need to get a return value.
For example if you want to disable the save button, save results to the server asynchronously and re-enable the save button when the job is done you can write it like this:
Future<bool> save() async {
// save changes async here
return true;
}
void saveClicked() {
saveButton.enabled = false;
save()
.then((success) => window.alert(success ? 'Saved' : 'Failed'))
.catchError((e) => window.alert(e))
.whenComplete(() { saveButton.enabled = true; });
}
Note that the saveClicked method is fully synchronous, but executes the save method asynchronously.
Note that if you make saveClicked async, not only do you have to call it using the async pattern, but the entire method body will run asynchronously so the save button will not be disabled when the function returns.
For completeness the async version of saveClicked looks like this:
Future<Null> saveClicked() async {
saveButton.enabled = false;
try {
bool success = await save();
window.alert(success ? 'Saved' : 'Failed');
}
catch (e) {
window.alert(e);
}
finally {
saveButton.enabled = true;
}
}
Yes, this is way late, but I think this is a cool feature new people should know about.
There is a way, but the Dart docs warn against it (and it's somehow "experimental", although the implications aren't really discussed).
The waitFor command.
You basically pass in an asynchronous function that returns a Future, an optional timeout parameter, and the waitFor function will return the result.
For example:
final int number = waitFor<int>(someAsyncThatReturnsInt);
The resync function cannot be implemented in Dart's current execution model.
Asynchronous execution is contagious. A synchronous function must return before any other asynchronous events can execute, so there is no way to synchronously wait for asynchronous execution.
Execution in Dart is single-threaded and event based. There is no way for the resync function to block without it also blocking all other execution in the same isolate, so the pending async operations will never happen.
To block the synchronous execution, and continue executing something else, you need to preserve the entire call stack up to that point, and reinstate it later when the synchronous operations have completed. If you have that functionality, then there are probably better ways to do things than Future and Stream :)
Also, waiting for "all async execution" isn't well-defined in an event based system. There might be a broadcast Stream emitting events coming in from the network, a periodic timer, or a receive port getting data from another isolate, or some other source of events that you can't wait for because they come from outside the isolate, or event the process. When the current isolate shuts down, it might send a final shut-down message to another isolate, so effectively the "async execution" isn't over until the isolate dies.
Using the async/await syntax, you won't get synchronous operation, but it will be easier to code the similar asynchronous operation:
function() async {
var result = await asyncFunction();
return result;
}
It won't wait for async operations that aren't reflected in the Future returned by asyncFunction, but that's the job of asyncFunction to not complete until its operations are complete.
Dart is inherently async. Trying to avoid asynchronity won't work out.
There are sync versions of some API calls for example in dart:io and in some situations it might seem simpler to use them instead but because there aren't sync versions for all methods/functions you can't avoid async entirely.
With the recent introduction of the async/await feature programming async become much simpler and the code looks almost like sync code (but it isn't).
If a call went async it stays async. As far as I know there is nothing you can do about it.
import 'package:synchronized_lite/synchronized_lite.dart';
import 'dart:async';
// Using Lock as a mixin to further mimic Java-style synchronized blocks
class SomeActivity with Lock {
bool _started = false;
Future<bool> start() async {
// It's correct to return a Future returned by synchronized()
return synchronized(() async {
if(_started)
return false;
// perform the start operation
await Future.delayed(Duration(seconds: 1));
print("Started");
_started = true;
return true;
});
}
Future<void> stop() async {
// It's also correct to await a synchronized() call before returning
// It's incorrect to neither await a synchronized() call nor return its Future.
await synchronized(() async {
if(!_started)
return;
// perform the stop operation`enter code here`
await Future.delayed(Duration(seconds: 1));
print("Stopped");
_started = false;
});
}
}
// Prints:
// Started
// Stopped
main() async {
var a = SomeActivity();
print("Hello");
a.start();
a.start();
a.stop();
await a.stop();
}
/*Since the Await statement can be used in only asynchronous methods. Then we do two methods.I thinking first we call the async method and then we constantly query the null result for the non-async method. Then we get a synchronized model. In this way, we will wait for the answer in the non-async method. Such a method comes to my mind. But as far as I can see, there is no escape from the async working model in flutter dart language. Need to get used to it.It may be unprofessional, but I wanted to share the solution that came to my mind. hope it helps.
Stock resultStockQueryByBarcodeAsync;
bool waitStockQueryByBarcodeAsyncCompleted = false;
Stock WaitStockQueryByBarcodeAsync(String barcode, int timeOut) {
CallStockQueryByBarcodeAsync(barcode);
var startTime = new DateTime.now();
while (!waitStockQueryByBarcodeAsyncCompleted) {
Duration difference = DateTime.now().difference(startTime);
if (difference.inMilliseconds > timeOut) {
throw TimeoutException("Timeout Exceeded");
}
//we must scope time. Because it can be enter endless loop.
}
return resultStockQueryByBarcodeAsync;
}
void CallStockQueryByBarcodeAsync(String barcode) async {
waitStockQueryByBarcodeAsyncCompleted = false;
resultStockQueryByBarcodeAsync = null;
var stock = await StockQueryByBarcodeAsync(barcode);/*your target async method*/
waitStockQueryByBarcodeAsyncCompleted = true;
resultStockQueryByBarcodeAsync = stock;
}
In my case, I had to initialize the database connection from constructor. I am pretty new in Flutter and I don't know what are the best practices right now. But, here is what I did.
class Storage {
late Database database;
Storage() {
getConnection().then((value) => database = value);
}
Future<Database> getConnection() async {
return await openDatabase('ims.db');
}
}
All I have done, is used the callback method to assign the value when the value is available.
Here's a solution based on staggering the start of the async function with start times at least 1 second apart, when calls come in almost simultaneously.
Steps:
Use the lastKnownTime to calculate the delta, where the initial value is 0
Once the delta is not some huge number, you know it's a duplicate call.
class StartConversationState extends State<StartConversationStatefulWidget> {
#override
Widget build(BuildContext context) {
_delayPush(); // this is the call that gets triggered multiple times
}
int lastKnownTime = 0;
int delayMillis = 3000;
_delayPush() async {
delayMillis += 1500;
await new Future.delayed(Duration(milliseconds: delayMillis));
int millisSinceEpoch = new DateTime.now().millisecondsSinceEpoch;
int delta = millisSinceEpoch - lastKnownTime;
// if delta is less than 10 seconds, means it was a subsequent interval
if (delta < 10000) {
print('_delayPush() , SKIPPING DUPLICATE CALL');
return;
}
// here is the logic you don't want to duplicate
// eg, insert DB record and navigate to next screen
}

Flutter : About error handling of timeout when retrieving documents of Firestore

I'm making an app with Flutter (Dart) and Firebase.
displayName = (await instance.collection('users').doc(ds.id).get())
.data()['displayName'];
When retrieving the Firestore document as described above, for example,
if I cannot get it after waiting 10 seconds,
I want to set the displayName to '' (empty string).
How should I write if I want to do something like that?
try {
Future.delayed(Duration(seconds:5,),(){
throw Exception('eeeeeewwwwwwwww');
});
await Future.delayed(Duration(seconds:10),);
//When I actually execute the code of ↓,
//there are almost no cases where it takes time to acquire (it can be acquired in a short time),
//so I tried to write a pseudo case like ↑ that can not be acquired.
/*
displayName = (await instance.collection('users').doc(ds.id).get())
.data()['displayName'];
url = (await instance.collection('users').doc(ds.id).get())
.data()['photoUrl'];
*/
}catch(e){
displayName='time out';
url=null;
continue;//(← Since it is in a for statement, if it takes 10 seconds or more, I want to skip to the next loop.)
}
The above code came to my mind, and I thought I could do it, but when I actually executed it,
The exception is thrown, but the catch clause is not executed (the exception was not caught).
I'm not sure why this doesn't work, but why not?
Is there a theory method for such cases?
When I googled, it says that when we use Dio, we can handle such timeout error by just setting the number of seconds (because it is in English, we can only understand the rough atmosphere).
However, the reason why people say "Dio looks good" is that if we don't use Dio, we have to write this kind of processing ourself, but with Dio we can easily do it?
You can try something like this although I haven't tested the code:
Future<String> fetchOrSetUser() async {
final String displayName;
try {
final userRef = await instance.collection('users').doc(ds.id).get().timeout(Duration(seconds: 10));
displayName = userRef.data()['displayName'];
} on TimeoutException catch (error) {
await instance.collection('users').doc(ds.id).update({
'displayName': ''
});
displayName = '';
} catch (error, _) {
rethrow;
}
return displayName;
}
It sets a timeout on the async call of 10 seconds and then tries to catch the TimeoutException. If that happens, it updates the userRef's displayName in the on TimeoutException block. I'm not sure if this would also fail if the user has no internet but I think updates can be written without internet... ?
Let me know if it doesn't work

When exactly do we use async-await and then?

I am very confused about this. I request you to clarify the concept.
Consider the following scenarios:
Case 1:
int number = 0;
void calculate() {
number = number + 2;
print(number);
}
I know this works just fine. "2" will be printed on the terminal.
But why shouldn't I use async-await here, like this:
int number = 0;
void calculate() async {
void addition() async {
number = number + 2;
}
await addition();
print(number);
}
This seems logical to me, since print(number) should wait for number = number + 2 to finish. Why isn't this necessary? How does dart know which operation to execute first?
How is it ensured that print(number) isn't executed before number = number + 2 and "0" is printed on the terminal?
Does the sequence in which we write these operations in the function matter?
Case 2:
Consider the case where I am interacting with SQFLite database and values fetched depend on each other.
Note: number1, number2, number3 will still have values before the following function is called.
void getValues() async {
void calculate1() {
number1 = await db.getNumber1(10);
}
void calculate2() {
number2 = await db.getNumber2(number1);
}
await calculate1().then((_) async {
await calculate2().then((_) async {
number3 = await db.getNumber3(number2);
});
});
}
I have a lot of these types of functions in my app and I am doing this everywhere.
I am kind of paranoid, thinking if old values of number1and number2 are taken as a parameter in getNumber2() and getNumber3() respectively, then I'll be doomed.
async/await are just syntax sugar for the underlying Future framework. 95% of the time, they will suffice, and are preferred by the style guide.
One exception is that you may have multiple futures that you want to wait until all are complete in parallel. In that case, you'll need to use Future.wait([future1, future2, future3]), which cannot be expressed using await.
Dart is executed line by line. So when the function is called calculation will be done first then it will be printed. So you will always get 2 printed
You can see it like there is one main thread in general which is the UI thread. Any operations you are writing in this thread will be performed line by line and after completely executing one line it will move to next line.
Now suppose you have something which you know that it will take time to be computed or fully executed with either a result or error. If you will write this in the main UI thread (synchronous thread) that means you're stopping the UI of the app, which in turn makes the app to crash(Application Not Responding Error) as the operating system feels that the app has frozen but as you know this is happening because of the compute you are running in the UI thread which is taking time and the UI is waiting for it to be completely executed.
So to overcome this issue we use Asynchronous methods to compute the time taking computations like getting some data from a database which will return a value or error in "future". The main UI thread doesn't waits for the asynchronous threads. If you don't have anything to show to the user until any asynchronous task is completed you place the loading indicators for the time being.
Hope this helps!

How to block until an async function completes [duplicate]

I'm on the way to evaluate Dart for a German company by porting various Java programs to Dart and compare and analyze the results. In the browser Dart wins hands down. For server software performance seemed to be a serious isssue (see this question of me) but that got mostly defused.
Now I'm in the area of porting some "simple" command-line tools where I did not expect any serious problems at all but there is at least one. Some of the tools do make HTTP requests to collect some data and the stand-alone Dart virtual machine only supports them in an asynchronous fashion. Looking through all I could find it does not seem to be possible to use any asynchronous call in a mostly synchronous software.
I understand that I could restructure the available synchronous software into an asynchronous one. But this would transform a well-designed piece of software into something less readable and more difficult to debug and maintain. For some software pieces this just does not make sense.
My question: Is there an (overlooked by me) way to embed an asynchronous call into a synchronously called method?
I imagine that it would not be to difficult to provide a system call, usable only from within the main thread, which just transfers the execution to the whole list of queued asynchronous function calls (without having to end the main thread first) and as soon as the last one got executed returns and continues the main thread.
Something which might look like this:
var synchFunction() {
var result;
asyncFunction().then(() { result = ...; });
resync(); // the system call to move to and wait out all async execution
return result;
}
Having such a method would simplify the lib APIs as well. Most "sync" calls could be removed because the re-synchronisation call would do the job. It seems to be such a logical idea that I still think it somehow exists and I have missed it. Or is there a serious reason why that would not work?
After thinking about the received answer from lm (see below) for two days I still do not understand why the encapsulation of an asynchronous Dart call into a synchronous one should not be possible. It is done in the "normal" synchronous programing world all the time. Usually you can wait for a resynchronization by either getting a "Done" from the asynchronous routine or if something fails continue after a timeout.
With that in mind my first proposal could be enhanced like that:
var synchFunction() {
var result;
asyncFunction()
.then(() { result = ...; })
.whenComplete(() { continueResync() }); // the "Done" message
resync(timeout); // waiting with a timeout as maximum limit
// Either we arrive here with the [result] filled in or a with a [TimeoutException].
return result;
}
The resync() does the same that would normally happen after ending the main method of an isolate, it starts executing the queued asynchronous functions (or waits for events to make them executable). As soon as it encounters a continueResync() call a flag is set which stops this asynchronous execution and resync() returns to the main thread. If no continueResync() call is encountered during the given timeout period it too aborts the asynchronous execution and leaves resync() with a TimeoutException.
For some groups of software which benefit from straight synchronous programing (not the client software and not the server software) such a feature would solve lots of problems for the programer who has to deal with asynchrounous-only libraries.
I believe that I have also found a solution for the main argument in lm's argumentation below. Therefore my question still stands with respect to this "enhanced" solution which I proposed: Is there anything which really makes it impossible to implement that in Dart?
The only time that you can wrap an async method in a synchronous one is when you don't need to get a return value.
For example if you want to disable the save button, save results to the server asynchronously and re-enable the save button when the job is done you can write it like this:
Future<bool> save() async {
// save changes async here
return true;
}
void saveClicked() {
saveButton.enabled = false;
save()
.then((success) => window.alert(success ? 'Saved' : 'Failed'))
.catchError((e) => window.alert(e))
.whenComplete(() { saveButton.enabled = true; });
}
Note that the saveClicked method is fully synchronous, but executes the save method asynchronously.
Note that if you make saveClicked async, not only do you have to call it using the async pattern, but the entire method body will run asynchronously so the save button will not be disabled when the function returns.
For completeness the async version of saveClicked looks like this:
Future<Null> saveClicked() async {
saveButton.enabled = false;
try {
bool success = await save();
window.alert(success ? 'Saved' : 'Failed');
}
catch (e) {
window.alert(e);
}
finally {
saveButton.enabled = true;
}
}
Yes, this is way late, but I think this is a cool feature new people should know about.
There is a way, but the Dart docs warn against it (and it's somehow "experimental", although the implications aren't really discussed).
The waitFor command.
You basically pass in an asynchronous function that returns a Future, an optional timeout parameter, and the waitFor function will return the result.
For example:
final int number = waitFor<int>(someAsyncThatReturnsInt);
The resync function cannot be implemented in Dart's current execution model.
Asynchronous execution is contagious. A synchronous function must return before any other asynchronous events can execute, so there is no way to synchronously wait for asynchronous execution.
Execution in Dart is single-threaded and event based. There is no way for the resync function to block without it also blocking all other execution in the same isolate, so the pending async operations will never happen.
To block the synchronous execution, and continue executing something else, you need to preserve the entire call stack up to that point, and reinstate it later when the synchronous operations have completed. If you have that functionality, then there are probably better ways to do things than Future and Stream :)
Also, waiting for "all async execution" isn't well-defined in an event based system. There might be a broadcast Stream emitting events coming in from the network, a periodic timer, or a receive port getting data from another isolate, or some other source of events that you can't wait for because they come from outside the isolate, or event the process. When the current isolate shuts down, it might send a final shut-down message to another isolate, so effectively the "async execution" isn't over until the isolate dies.
Using the async/await syntax, you won't get synchronous operation, but it will be easier to code the similar asynchronous operation:
function() async {
var result = await asyncFunction();
return result;
}
It won't wait for async operations that aren't reflected in the Future returned by asyncFunction, but that's the job of asyncFunction to not complete until its operations are complete.
Dart is inherently async. Trying to avoid asynchronity won't work out.
There are sync versions of some API calls for example in dart:io and in some situations it might seem simpler to use them instead but because there aren't sync versions for all methods/functions you can't avoid async entirely.
With the recent introduction of the async/await feature programming async become much simpler and the code looks almost like sync code (but it isn't).
If a call went async it stays async. As far as I know there is nothing you can do about it.
import 'package:synchronized_lite/synchronized_lite.dart';
import 'dart:async';
// Using Lock as a mixin to further mimic Java-style synchronized blocks
class SomeActivity with Lock {
bool _started = false;
Future<bool> start() async {
// It's correct to return a Future returned by synchronized()
return synchronized(() async {
if(_started)
return false;
// perform the start operation
await Future.delayed(Duration(seconds: 1));
print("Started");
_started = true;
return true;
});
}
Future<void> stop() async {
// It's also correct to await a synchronized() call before returning
// It's incorrect to neither await a synchronized() call nor return its Future.
await synchronized(() async {
if(!_started)
return;
// perform the stop operation`enter code here`
await Future.delayed(Duration(seconds: 1));
print("Stopped");
_started = false;
});
}
}
// Prints:
// Started
// Stopped
main() async {
var a = SomeActivity();
print("Hello");
a.start();
a.start();
a.stop();
await a.stop();
}
/*Since the Await statement can be used in only asynchronous methods. Then we do two methods.I thinking first we call the async method and then we constantly query the null result for the non-async method. Then we get a synchronized model. In this way, we will wait for the answer in the non-async method. Such a method comes to my mind. But as far as I can see, there is no escape from the async working model in flutter dart language. Need to get used to it.It may be unprofessional, but I wanted to share the solution that came to my mind. hope it helps.
Stock resultStockQueryByBarcodeAsync;
bool waitStockQueryByBarcodeAsyncCompleted = false;
Stock WaitStockQueryByBarcodeAsync(String barcode, int timeOut) {
CallStockQueryByBarcodeAsync(barcode);
var startTime = new DateTime.now();
while (!waitStockQueryByBarcodeAsyncCompleted) {
Duration difference = DateTime.now().difference(startTime);
if (difference.inMilliseconds > timeOut) {
throw TimeoutException("Timeout Exceeded");
}
//we must scope time. Because it can be enter endless loop.
}
return resultStockQueryByBarcodeAsync;
}
void CallStockQueryByBarcodeAsync(String barcode) async {
waitStockQueryByBarcodeAsyncCompleted = false;
resultStockQueryByBarcodeAsync = null;
var stock = await StockQueryByBarcodeAsync(barcode);/*your target async method*/
waitStockQueryByBarcodeAsyncCompleted = true;
resultStockQueryByBarcodeAsync = stock;
}
In my case, I had to initialize the database connection from constructor. I am pretty new in Flutter and I don't know what are the best practices right now. But, here is what I did.
class Storage {
late Database database;
Storage() {
getConnection().then((value) => database = value);
}
Future<Database> getConnection() async {
return await openDatabase('ims.db');
}
}
All I have done, is used the callback method to assign the value when the value is available.
Here's a solution based on staggering the start of the async function with start times at least 1 second apart, when calls come in almost simultaneously.
Steps:
Use the lastKnownTime to calculate the delta, where the initial value is 0
Once the delta is not some huge number, you know it's a duplicate call.
class StartConversationState extends State<StartConversationStatefulWidget> {
#override
Widget build(BuildContext context) {
_delayPush(); // this is the call that gets triggered multiple times
}
int lastKnownTime = 0;
int delayMillis = 3000;
_delayPush() async {
delayMillis += 1500;
await new Future.delayed(Duration(milliseconds: delayMillis));
int millisSinceEpoch = new DateTime.now().millisecondsSinceEpoch;
int delta = millisSinceEpoch - lastKnownTime;
// if delta is less than 10 seconds, means it was a subsequent interval
if (delta < 10000) {
print('_delayPush() , SKIPPING DUPLICATE CALL');
return;
}
// here is the logic you don't want to duplicate
// eg, insert DB record and navigate to next screen
}