0

I want to read bulk audio file's tags faster. currently i am able to store 5000 audio files info to struct list in about 7 seconds.

issue is when i select folder having 20,000 or 40,000 files the app keeps on running and doesn't notify that the process is done. whereas when it reads 5,000 files it shows the message box prompting "Done loading files 5000" in 7 seconds.

Here is my code:

        public struct SongInfoStruct
        {
            public string Key;
            public string Value;
            public string Artist;
            public double Duration;
            public string Comments;
            public string Album;
            public string Missing;
        };

        public async Task<SongInfoStruct> GetSongInfo(string url)
        {
            var songinfo = (dynamic)null;
            var tagFile = TagLib.File.Create(url);
            var songName = (dynamic)null;
            var artist = (dynamic)null;
            var album = (dynamic)null;
            var comments = (dynamic)null;
            var duration = (dynamic)null;

            await Task.Run(() =>
            {
               songName = tagFile.Tag.Title;
               artist = tagFile.Tag.FirstPerformer;
               album = tagFile.Tag.Album;
               comments = tagFile.Tag.Comment;
               duration = tagFile.Properties.Duration.TotalSeconds;
            });

            return songinfo = new SongInfoStruct
            {
                Key = url,
                Value = songName,
                Artist = artist,
                Duration = duration,
                Comments = comments,
                Album = album,
                Missing = " "
            };
        }

        public async Task<List<SongInfoStruct>> ReadPathFromSource(string Source)
        {
            var files = Directory.EnumerateFiles(Source, "*", 
            SearchOption.AllDirectories).Where(s => s.EndsWith(".mp3") || 
            s.EndsWith(".m4a"));
            int length = files.Count();
            var listpaths = new List<SongInfoStruct>(length);
            listpaths.Clear();
            foreach (string PathsClickSong_temp in files)
            {
                var item = await GetSongInfo(PathsClickSong_temp);

                await Task.Run(() =>
                {
                    listpaths.Add(item);
                });
            }
            MessageBox.Show("Done loading files "+ listpaths.Count.ToString());
            return listpaths;
        }
ansa hj
  • 35
  • 7

1 Answers1

0

As a good practice, always try to set ConfigureAwait to false, unless you want to use same caller context.

var item = await GetSongInfo(PathsClickSong_temp).ConfigureAwait(false);

Here, you can try it using Task.WhenAll instead, which gets multiple data concurrently. Task.Run is good to use when there is CPU intense work, for detail please have a look at When correctly use Task.Run and when just async-await

 var listpaths = new List<Task<SongInfoStruct>>(length);
 listpaths.Clear();
            
 foreach (string PathsClickSong_temp in files)
 {
    var item = GetSongInfo(PathsClickSong_temp);
    listpaths.Add(item);
              
  }
 await Task.WhenAll(listpaths);
mabiyan
  • 667
  • 7
  • 25
  • `listpaths.Add(item);` **Error : Cannot convert from SongInfoStruct to System.Threading.Tasks.Task** Also how am i supposed to return listpath and what should be the return type of the fucntion "ReadPathFromSource" – ansa hj Mar 14 '22 at 13:32
  • make sure you are adding `Task` as an item to your list, `List>` , you can use `Result` property of the response of `Task.WhenAll` – mabiyan Mar 14 '22 at 15:08