C# 多线程 07-使用 PLINQ 06-为 PLINQ 查询创建一个自定义的聚合器
🏷️ 《C# 多线程》
示例代码
csharp
/// <summary>
/// 为 PLINQ 查询创建一个自定义的聚合器
/// 统计集合中所有字母出现的频率
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
var parallelQuery = from t in GetTypes().AsParallel()
select t;
var parallelAggregator = parallelQuery.Aggregate(
// 一个工厂类
() => new ConcurrentDictionary<char, int>(),
// 每个分区的聚合函数
(taskTotal, item) => AccumulateLettersInformation(taskTotal, item),
// 高阶聚合函数
(total, taskTotal) => MergeAccululators(total, taskTotal),
// 选择器函数(指定全局对象中我们需要的确切数据)
total => total);
Console.WriteLine();
Console.WriteLine("There were the following letters in type names:");
// 按字符出现的频率排序
var orderedKeys = from k in parallelAggregator.Keys
orderby parallelAggregator[k] descending
select k;
// 打印聚合结果
foreach (var c in orderedKeys)
{
Console.WriteLine($"Letter '{c}' ---- {parallelAggregator[c]} times");
}
Console.ReadLine();
}
static ConcurrentDictionary<char, int> AccumulateLettersInformation(ConcurrentDictionary<char, int> taskTotal, string item)
{
foreach (var c in item)
{
if (taskTotal.ContainsKey(c))
{
taskTotal[c] += 1;
}
else
{
taskTotal[c] = 1;
}
}
Console.WriteLine($"{item} type was aggregated on a thread id {Thread.CurrentThread.ManagedThreadId}");
return taskTotal;
}
static ConcurrentDictionary<char, int> MergeAccululators(ConcurrentDictionary<char, int> total, ConcurrentDictionary<char, int> taskTotal)
{
foreach (var key in taskTotal.Keys)
{
if (total.ContainsKey(key))
{
total[key] += taskTotal[key];
} else
{
total[key] = 1;
}
}
Console.WriteLine("---");
Console.WriteLine($"Total aggregate value was calculated on a thread in {Thread.CurrentThread.ManagedThreadId}");
return total;
}
static IEnumerable<string> GetTypes()
{
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetExportedTypes());
return from type in types
where type.Name.StartsWith("Web")
select type.Name;
}
执行结果
WebClient type was aggregated on a thread id 1
WebHeaderCollection type was aggregated on a thread id 1
WebPermissionAttribute type was aggregated on a thread id 1
WebExceptionStatus type was aggregated on a thread id 3
WebProxy type was aggregated on a thread id 3
WebException type was aggregated on a thread id 4
WebRequestMethods type was aggregated on a thread id 5
WebUtility type was aggregated on a thread id 5
WebSocket type was aggregated on a thread id 5
WebSocketCloseStatus type was aggregated on a thread id 5
WebSocketContext type was aggregated on a thread id 5
WebResponse type was aggregated on a thread id 4
WebSocketException type was aggregated on a thread id 4
WebSocketMessageType type was aggregated on a thread id 4
WebRequest type was aggregated on a thread id 3
WebSocketState type was aggregated on a thread id 3
WebSocketReceiveResult type was aggregated on a thread id 4
WebSocketError type was aggregated on a thread id 5
WebProxyScriptElement type was aggregated on a thread id 3
WebRequestModuleElement type was aggregated on a thread id 3
WebPermission type was aggregated on a thread id 1
WebRequestModuleElementCollection type was aggregated on a thread id 3
WebUtilityElement type was aggregated on a thread id 5
WebRequestModulesSection type was aggregated on a thread id 4
---
Total aggregate value was calculated on a thread in 1
---
Total aggregate value was calculated on a thread in 1
---
Total aggregate value was calculated on a thread in 1
There were the following letters in type names:
Letter 'e' ---- 78 times
Letter 't' ---- 42 times
Letter 'o' ---- 28 times
Letter 'b' ---- 25 times
Letter 'W' ---- 24 times
Letter 's' ---- 19 times
Letter 'i' ---- 18 times
Letter 'c' ---- 16 times
Letter 'l' ---- 16 times
Letter 'n' ---- 15 times
Letter 'S' ---- 13 times
Letter 'u' ---- 12 times
Letter 'r' ---- 10 times
Letter 'E' ---- 8 times
Letter 'R' ---- 8 times
Letter 'k' ---- 8 times
Letter 'p' ---- 6 times
Letter 'x' ---- 6 times
Letter 'm' ---- 6 times
Letter 'C' ---- 5 times
Letter 'd' ---- 5 times
Letter 'q' ---- 5 times
Letter 'M' ---- 5 times
Letter 'y' ---- 5 times
Letter 'a' ---- 5 times
Letter 'P' ---- 4 times
Letter 'h' ---- 1 times
Letter 'v' ---- 1 times
Letter 'A' ---- 1 times
Letter 'T' ---- 1 times
Letter 'H' ---- 1 times
Letter 'g' ---- 1 times
Letter 'U' ---- 1 times