Multithreading for MultiMethods in Flutter

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 awaits 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)

Leave a Reply

Your email address will not be published. Required fields are marked *