Обновление 20 мая 2011 г., 00:49: foreach по-прежнему на 25% быстрее, чем параллельное решение для моего приложения. И не используйте количество коллекций для максимального параллелизма, используйте что-то близкое к количеству ядер на вашей машине.
=
У меня есть связанная с вводом-выводом задача, которую я хотел бы запустить параллельно. Я хочу применить одну и ту же операцию к каждому файлу в папке. Внутри операция приводит к Dispatcher.Invoke, который добавляет вычисляемую информацию о файле в коллекцию в потоке пользовательского интерфейса. Таким образом, в некотором смысле результат работы является побочным эффектом вызова метода, а не значением, возвращаемым непосредственно из вызова метода.
Это основной цикл, который я хочу запустить параллельно.
foreach (ShellObject sf in sfcoll)
ProcessShellObject(sf, curExeName);
Контекст для этого цикла здесь:
var curExeName = Path.GetFileName(Assembly.GetEntryAssembly().Location);
using (ShellFileSystemFolder sfcoll = ShellFileSystemFolder.FromFolderPath(_rootPath))
{
//This works, but is not parallel.
foreach (ShellObject sf in sfcoll)
ProcessShellObject(sf, curExeName);
//This doesn't work.
//My attempt at PLINQ. This code never calls method ProcessShellObject.
var query = from sf in sfcoll.AsParallel().WithDegreeOfParallelism(sfcoll.Count())
let p = ProcessShellObject(sf, curExeName)
select p;
}
private String ProcessShellObject(ShellObject sf, string curExeName)
{
String unusedReturnValueName = sf.ParsingName
try
{
DesktopItem di = new DesktopItem(sf);
//Up date DesktopItem stuff
di.PropertyChanged += new PropertyChangedEventHandler(DesktopItem_PropertyChanged);
ControlWindowHelper.MainWindow.Dispatcher.Invoke(
(Action)(() => _desktopItemCollection.Add(di)));
}
catch (Exception ex)
{
}
return unusedReturnValueName ;
}
Спасибо за любую помощь!
+том