Issue
may i ask how to multithreading some functions in dart
for example i have 16 Future functions
i want first to execute this function in the first thread
await GetRoot(); //Future<void>
then after the first thread end i want to execute theses functions in the second thread –togather at the same time–
await GetLocalRadio();//Future<void>
await GetMusic();//Future<void>
await GetTalk();//Future<void>
await GetSports();//Future<void>
await GetByLocation();//Future<void>
await GetByLanguage();//Future<void>
await GetPodcasts();//Future<void>
then after the second thread is finished , i want to execute these threads togather at the same time in the next thread
await GetPodcasts2();//Future<void>
await GetByLocation2();//Future<void>
then when the second thread end i want when the third functions is finished to execute these functions togather at the same time in a new thread
await FillPdcasts();//Future<void>
await FillLocalRadio();//Future<void>
await FillMusic();//Future<void>
await FillTalk();//Future<void>
await FillSports();//Future<void>
await FillByLocation();//Future<void>
here is a simple of the content of all methods that i have
Future<void> FillByLocation()
async {
for (var entry in xByLocation2) {
final responseFinalByLocation2 = await http.Client().get(entry.split('^')[1], headers: {'Content-Type': 'application/json; charset=utf-8'});
try{
final FinalByLocation2final = allInfosFromJson(utf8.decode(responseFinalByLocation2.bodyBytes));
for (int i = 0; i < FinalByLocation2final.body.length; i++) {
for (int j = 0; j < FinalByLocation2final.body[i].children.length; j++) {
if(FinalByLocation2final.body[i].children[j].text != null && FinalByLocation2final.body[i].children[j].image != null)
{
if(!xListFinalAllInfos.contains(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image))
{
setState(() {
xListFinalAllInfos.add(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image);
// ListFinalAllInfos.putIfAbsent(
// FinalByLocation2final.body[i].children[j].text, () =>
// FinalByLocation2final.body[i].children[j].image );
});
}
}
}
}
}catch(e){}
}
}
Because when I execute all the functions and await all of them, then this will take about 30 seconds.
This is a lot of time, so I need to make the time less than 30 seconds.
Solution
Multithreading is not an option here. Just stick with asynchrony.
All of your await
s are making your code much slower. You’re forcing the previous function to finish before the next function can even start. Call them all at the same time and use Future.wait
.
await GetRoot();
List<Future<void>> toWait = [];
toWait.add(GetLocalRadio());
toWait.add(GetMusic());
...
await Future.wait(toWait);
toWait.clear();
toWait.add(GetPodcasts2());
toWait.add(GetByLocation2());
await Future.wait(toWait);
toWait.clear();
toWait.add(FillPdcasts());
toWait.add(FillLocalRadio());
...
await Future.wait(toWait);
toWait.clear();
Additionally, the work you’re doing within these function is also implemented inefficiently. You’re waiting for each http call to finish before processing the data from the call and starting the next one. This can be made more efficient.
The following code uses .then
to register callbacks for each of the network calls, stores the futures to a list, and uses Future.wait
at the very end to ensure they’re all completed before the wrapper function returns.
Future<void> FillByLocation()
async {
List<Future<void>> toWait = [];
for (var entry in xByLocation2) {
toWait.add(http.Client().get(entry.split('^')[1], headers: {'Content-Type': 'application/json; charset=utf-8'}).then((responseFinalByLocation2){
try{
final FinalByLocation2final = allInfosFromJson(utf8.decode(responseFinalByLocation2.bodyBytes));
for (int i = 0; i < FinalByLocation2final.body.length; i++) {
for (int j = 0; j < FinalByLocation2final.body[i].children.length; j++) {
if(FinalByLocation2final.body[i].children[j].text != null && FinalByLocation2final.body[i].children[j].image != null)
{
if(!xListFinalAllInfos.contains(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image))
{
setState(() {
xListFinalAllInfos.add(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image);
// ListFinalAllInfos.putIfAbsent(
// FinalByLocation2final.body[i].children[j].text, () =>
// FinalByLocation2final.body[i].children[j].image );
});
}
}
}
}
}catch(e){}
}));
}
await Future.wait(toWait);
}
Answered By – Christopher Moore
Answer Checked By – Cary Denson (FlutterFixes Admin)