更新 2011-05-20 12:49AM: 私のアプリケーションでは、foreach は並列ソリューションよりも 25% 高速です。また、最大並列処理にコレクション数を使用しないでください。マシンのコア数に近いものを使用してください。
=
並行して実行したい IO バインド タスクがあります。フォルダ内のすべてのファイルに同じ操作を適用したい。内部的には、操作の結果、計算されたファイル情報を UI スレッドのコレクションに追加する 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 ;
}
助けてくれてありがとう!
+トム