我想知道我是否应该在我的案例中使用Parallel.ForEach()。关于一些上下文:我正在使用NAudio库开发一个小型音乐播放器。我希望在工厂方法中使用Parallel.ForEach()来快速访问.mp3文件并创建TrackModel对象来表示它们(大约400个)。代码如下所示:
public static List<TrackModel> CreateTracks(string[] files)
{
// Guard Clause
if (files == null || files.Length == 0) throw new ArgumentException();
var output = new List<TrackModel>();
TrackModel track;
Parallel.ForEach(files, file =>
{
using (MusicPlayer musicPlayer = new MusicPlayer(file, 0f))
{
track = new TrackModel()
{
FilePath = file,
Title = File.Create(file).Tag.Title,
Artist = File.Create(file).Tag.FirstPerformer,
TrackLength = musicPlayer.GetLengthInSeconds(),
};
}
lock (output)
{
output.Add(track);
}
});
return output;
}注意:我使用lock防止多个线程同时向列表中添加元素。
我的问题是:在这种情况下我应该使用Parallel.ForEach()还是编写一个普通的foreach循环更好?这是实现更好性能的正确方法吗?我应该首先结合使用多线程和文件访问吗?
发布于 2022-07-17 04:10:20
最好同时避免foreach和Parallel.ForEach。在这种情况下,AsParallel()是你的朋友。
试试这个:
public static List<TrackModel> CreateTracks(string[] files)
{
if (files == null || files.Length == 0) throw new ArgumentException();
return
files
.AsParallel()
.AsOrdered()
.WithDegreeOfParallelism(2)
.Select(file =>
{
using (MusicPlayer musicPlayer = new MusicPlayer(file, 0f))
{
return new TrackModel()
{
FilePath = file,
Title = File.Create(file).Tag.Title,
Artist = File.Create(file).Tag.FirstPerformer,
TrackLength = musicPlayer.GetLengthInSeconds(),
};
}
})
.ToList();
}这将为您处理所有并行逻辑和幕后锁定。
发布于 2022-07-17 12:04:52
结合来自评论和答案的建议并根据我的代码进行调整,我能够用以下代码解决我的问题:
public List<TrackModel> CreateTracks(string[] files)
{
var output = files
.AsParallel()
.Select(file =>
{
using MusicPlayer musicPlayer = new MusicPlayer(file, 0f);
using File musicFile = File.Create(file);
return new TrackModel()
{
FilePath = file,
Title = musicFile.Tag.Title,
Artist = musicFile.Tag.FirstPerformer,
Length = musicPlayer.GetLengthInSeconds(),
};
})
.ToList();
return output;
}使用AsParallel()大大缩短了加载时间,这正是我所要寻找的。由于这个聪明的想法,我将Enigmativity的答案标记为正确。最初,它抛出了一个奇怪的AggregateException,但是我能够通过将输出保存在一个变量中,然后返回它来解决它。
这也归功于marsze,它的建议帮助我修复了应用程序中的内存泄漏,并减少了16 me的内存(!)。
https://stackoverflow.com/questions/73004174
复制相似问题