您可以使用Interlocked.Increment
生成的ID,或者你可以直接使用索引:
List<FileInfo> files = GetFilesToProcess();
files.AsParallel().Select((f, i) => new {File=f, ID=i})
.ForAll(fp =>
{
FileInfo file = fp.File;
int id = fp.ID; // ID is the index in the list
// Process file here
});
如果你想使用Interlocked.Increment
,你可以這樣做:
List<FileInfo> files = GetFilesToProcess();
int globalId = -1;
files.AsParallel().ForAll(f =>
{
// Process file here
int id = Interlocked.Increment(ref globalId);
// use ID
});
話雖這麼說,如果你的整個目標是對一個集合做「工作」,我會建議把它寫成一個Parallel.For或者Parallel.ForEach。這是更爲明確的,因爲你不使用LINQ風格的語法產生副作用的唯一目的:
List<FileInfo> files = GetFilesToProcess();
Parallel.For(0, files.Count, i =>
{
var file = files[i];
// Use i and file as needed
});
嗨裏德,感謝您提出的解決方案和答覆。我只想澄清一下,如果我使用Parallel For/ForEach,它將像ForAll一樣並行執行?對不起,如果你認爲這是一個愚蠢的問題。只是想確定。 – lionheart
@lionheart是的 - 這是兩種不同的方法。通常,如果您正在執行某種形式的過濾操作('.Where')或映射操作('.Select'),則可以使用PLINQ('.AsParallel()')。剛剛引入'.ForAll()'方法來簡化您在處理「查詢」結果時的工作。如果你的目標僅僅是「並行地做一些工作」,那麼'Parallel.For'和'Parallel.ForEach'更合適。對於一個很好的理由,爲什麼,請閱讀:http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx –
太棒了!謝謝里德! – lionheart