【发布时间】:2014-04-02 19:43:52
【问题描述】:
我现在正在用 TPL 类替换我的旧并行化帮助程序类。当操作代码中出现错误时,我的旧代码已被证明非常不可靠,而且它似乎不是为我现在正在做的事情而构建的。
第一个工作列表很容易翻译成Parallel.ForEach。但是这里有一个嵌套和索引的循环,我不能这么容易解决。
int streamIndex = 0;
foreach (var playlist in selectedPlaylists)
{
var localPlaylist = playlist;
foreach (var streamFile in playlist.StreamFiles)
{
var localStreamFile = streamFile;
var localStreamIndex = streamIndex++;
// Action that uses localPlaylist, localStreamFile and localStreamIndex
...
// Save each job's result to its assigned place in the list
lock (streamsList)
{
streamsList[localStreamIndex] = ...;
}
}
}
局部变量用于正确的闭包支持,因为 foreach 迭代变量是共享的。
我正在考虑类似的事情
selectedPlaylists.SelectMany(p => p.StreamFiles)
但是我失去了每个流文件来自哪里的关联,以及应该是确定性的索引,因为它用于对结果列表中的结果进行排序。有没有办法保持这些与 Linq 的关联,并在枚举列表时添加该计数器?可能是这样(虚构的伪代码):
selectedPlaylists
.SelectMany(p => new
{
Playlist = p,
StreamFile = ~~each one of p.StreamFiles~~,
Index = ~~Counter()~~
})
我可以保留那些旧的嵌套 foreach 循环并将所有作业收集到一个列表中,然后使用 Parallel.Invoke,但这似乎比它需要的更复杂。我想知道是否有一个我还不知道的简单 Linq 功能。
【问题讨论】:
-
查看我对 Cancelationtoken 和并行度的编辑