C# 操作块 await 不能按预期工作

C# action block await doesnt work as expected

问题似乎是在一些异步块完成之前等待触发。 要么是因为我做了某事,但物体不支持,要么更有可能是我搞砸了。但是由于问题需要很多代码才能发生,所以它被认为是代码转储 =(

我希望这能有所帮助。

我放弃了 Broadcastblock 并切换到基于任务的管道。

为需要对自己的输入具有写入权限的爬虫使用任务工厂: https://msdn.microsoft.com/en-us/library/ff963548.aspx

解决了问题。

这些同步版本非常适合慢速 producers/fast 消费者

taskfactory -> 创建你的任务,并通过 BlockingCollection 连接它们, 可悲的是,你不能让一个 foreach 消耗可枚举的最后一个标志(这对爬虫来说很好)

我相信 Complete 方法可以满足您的需要。这里的文档有一个很好的例子:

https://msdn.microsoft.com/en-us/library/hh194731%28v=vs.110%29.aspx

好的,尝试用这个替换你的合并方法:

 private static async Task merge(Func<ConcurrentDictionary<string,int>> getter, Action<ConcurrentDictionary<string,int>> setter, List<parserPart>list)
        {
            List<Task> tasks  = new List<Task>();
            var target = getter();
            int buffer;
            foreach (parserPart b in list)
            {
                tasks.Add(Task.Factory.StartNew( () => {
                    target.TryGetValue(b.uploader_id, out buffer);
                    target.TryAdd(b.uploader_id, (buffer + b.count));
                }
            }
            Task.WaitAll(tasks.ToArray()); 
            await Task.Run(() => setter(target));
            Console.Writeline("merging task");
        }
    }

此外,在等待完成之前使用 Complete 方法:

splitter.Complete();
sorter.Complete();
await Task.WhenAll(svn, splitter.Completion, sorter.Completion);

P.S。 .. 我没有测试过这个,因为要复制的代码太多了,但是你确实说过你的合并方法在你得到一些结果后保持 运行 ,所以,通过创建任务列表,你可以等待在获得结果之前完成整个列表。