Skip to content

C# 多线程 07-使用 PLINQ 02-PLINQ 查询

🏷️ 《C# 多线程》

示例代码

csharp
/// <summary>
/// PLINQ 查询
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
    var sw = new Stopwatch();
    sw.Start();
    // 正常的顺序 LINQ 查询
    // 所有操作都运行在当前线程
    var query = from t in GetTypes()
                select EmulateProcessing(t);

    foreach (string typeName in query)
    {
        PrintInfo(typeName);
    }

    sw.Stop();
    Console.WriteLine("---");
    Console.WriteLine("Sequential LINQ query.");
    Console.WriteLine("正常的顺序 LINQ 查询");
    Console.WriteLine("所有操作都运行在当前线程");
    Console.WriteLine($"Time elapsed: {sw.Elapsed}");
    Console.WriteLine("Press Enter to continue....");
    Console.ReadLine();
    Console.Clear();
    sw.Reset();

    sw.Start();
    // 使用 AsParallel 方法将查询并行化
    // 默认情况下结果会被合并到单个线程中
    var paralleQuery = from t in GetTypes().AsParallel()
                        select EmulateProcessing(t);
    foreach (var typeName in paralleQuery)
    {
        PrintInfo(typeName);
    }
    sw.Stop();
    Console.WriteLine("---");
    Console.WriteLine("Parallel LINQ query. The results are being merged on a single thrad");
    Console.WriteLine("使用 AsParallel 方法将查询并行化");
    Console.WriteLine("默认情况下结果会被合并到单个线程中");
    Console.WriteLine($"Time elapsed: {sw.Elapsed}");
    Console.WriteLine("Press Enter to continue....");
    Console.ReadLine();
    Console.Clear();
    sw.Reset();


    sw.Start();
    // 使用 AsParallel 方法将查询并行化
    paralleQuery = from t in GetTypes().AsParallel()
                    select EmulateProcessing(t);
    // 使用 ForAll 方法将打印操作和查询操作放到了同一个线程,跳过了结果合并的步骤
    paralleQuery.ForAll(PrintInfo);

    sw.Stop();
    Console.WriteLine("---");
    Console.WriteLine("Parallel LINQ query. The results are being processed in parallel");
    Console.WriteLine("使用 ForAll 方法将打印操作和查询操作放到了同一个线程,跳过了结果合并的步骤");
    Console.WriteLine($"Time elapsed: {sw.Elapsed}");
    Console.WriteLine("Press Enter to continue....");
    Console.ReadLine();
    Console.Clear();
    sw.Reset();


    sw.Start();
    // 使用 AsSequential 方法将 PLINQ 查询已顺序方式执行
    query = from t in GetTypes().AsParallel().AsSequential()
            select EmulateProcessing(t);
    foreach (string typeName in query)
    {
        PrintInfo(typeName);
    }

    sw.Stop();
    Console.WriteLine("---");
    Console.WriteLine("Parallel LINQ query, transformed into sequential.");
    Console.WriteLine("使用 AsSequential 方法将 PLINQ 查询以顺序方式执行");
    Console.WriteLine("运行结果同第一个示例完全一样");
    Console.WriteLine($"Time elapsed: {sw.Elapsed}");
    Console.WriteLine("Press Enter to continue....");
    Console.ReadLine();
    Console.Clear();
    sw.Reset();
}

static void PrintInfo(string typeName)
{
    Thread.Sleep(TimeSpan.FromMilliseconds(15));
    Console.WriteLine($"{typeName} type was printed on a thread id {Thread.CurrentThread.ManagedThreadId}");
}

static string EmulateProcessing(string typeName)
{
    Thread.Sleep(TimeSpan.FromMilliseconds(150));
    Console.WriteLine($"{typeName} type was processed on a thread id {Thread.CurrentThread.ManagedThreadId}");
    return typeName;
}

/// <summary>
/// 使用反射 API 查询加载到当前应用程序域中的所有组件中名称以“Web”开头的类型
/// </summary>
/// <returns></returns>
static IEnumerable<string> GetTypes()
{
    return from assembly in AppDomain.CurrentDomain.GetAssemblies()
            from type in assembly.GetExportedTypes()
            where type.Name.StartsWith("Web")
            select type.Name;
}

运行结果

示例一

点击查看运行结果
txt
WebRequestMethods type was processed on a thread id 1
WebRequestMethods type was printed on a thread id 1
WebClient type was processed on a thread id 1
WebClient type was printed on a thread id 1
WebException type was processed on a thread id 1
WebException type was printed on a thread id 1
WebExceptionStatus type was processed on a thread id 1
WebExceptionStatus type was printed on a thread id 1
WebHeaderCollection type was processed on a thread id 1
WebHeaderCollection type was printed on a thread id 1
WebPermissionAttribute type was processed on a thread id 1
WebPermissionAttribute type was printed on a thread id 1
WebPermission type was processed on a thread id 1
WebPermission type was printed on a thread id 1
WebProxy type was processed on a thread id 1
WebProxy type was printed on a thread id 1
WebRequest type was processed on a thread id 1
WebRequest type was printed on a thread id 1
WebResponse type was processed on a thread id 1
WebResponse type was printed on a thread id 1
WebUtility type was processed on a thread id 1
WebUtility type was printed on a thread id 1
WebSocket type was processed on a thread id 1
WebSocket type was printed on a thread id 1
WebSocketCloseStatus type was processed on a thread id 1
WebSocketCloseStatus type was printed on a thread id 1
WebSocketContext type was processed on a thread id 1
WebSocketContext type was printed on a thread id 1
WebSocketError type was processed on a thread id 1
WebSocketError type was printed on a thread id 1
WebSocketException type was processed on a thread id 1
WebSocketException type was printed on a thread id 1
WebSocketMessageType type was processed on a thread id 1
WebSocketMessageType type was printed on a thread id 1
WebSocketReceiveResult type was processed on a thread id 1
WebSocketReceiveResult type was printed on a thread id 1
WebSocketState type was processed on a thread id 1
WebSocketState type was printed on a thread id 1
WebProxyScriptElement type was processed on a thread id 1
WebProxyScriptElement type was printed on a thread id 1
WebRequestModuleElement type was processed on a thread id 1
WebRequestModuleElement type was printed on a thread id 1
WebRequestModuleElementCollection type was processed on a thread id 1
WebRequestModuleElementCollection type was printed on a thread id 1
WebRequestModulesSection type was processed on a thread id 1
WebRequestModulesSection type was printed on a thread id 1
WebUtilityElement type was processed on a thread id 1
WebUtilityElement type was printed on a thread id 1
---
Sequential LINQ query.
正常的顺序LINQ查询
所有操作都运行在当前线程
Time elapsed: 00:00:03.9686277
Press Enter to continue....

示例二

点击查看运行结果
txt
WebException type was processed on a thread id 5
WebExceptionStatus type was processed on a thread id 6
WebRequestMethods type was processed on a thread id 3
WebClient type was processed on a thread id 4
WebProxy type was processed on a thread id 4
WebPermission type was processed on a thread id 3
WebHeaderCollection type was processed on a thread id 5
WebPermissionAttribute type was processed on a thread id 6
WebRequest type was processed on a thread id 4
WebUtility type was processed on a thread id 5
WebResponse type was processed on a thread id 3
WebSocket type was processed on a thread id 6
WebSocketCloseStatus type was processed on a thread id 4
WebSocketException type was processed on a thread id 6
WebSocketContext type was processed on a thread id 5
WebSocketError type was processed on a thread id 3
WebSocketMessageType type was processed on a thread id 4
WebSocketReceiveResult type was processed on a thread id 6
WebSocketState type was processed on a thread id 5
WebProxyScriptElement type was processed on a thread id 3
WebUtilityElement type was processed on a thread id 3
WebRequestModuleElementCollection type was processed on a thread id 6
WebRequestModuleElement type was processed on a thread id 4
WebRequestModulesSection type was processed on a thread id 5
WebRequestMethods type was printed on a thread id 1
WebException type was printed on a thread id 1
WebExceptionStatus type was printed on a thread id 1
WebClient type was printed on a thread id 1
WebPermission type was printed on a thread id 1
WebHeaderCollection type was printed on a thread id 1
WebPermissionAttribute type was printed on a thread id 1
WebProxy type was printed on a thread id 1
WebResponse type was printed on a thread id 1
WebUtility type was printed on a thread id 1
WebSocket type was printed on a thread id 1
WebRequest type was printed on a thread id 1
WebSocketError type was printed on a thread id 1
WebSocketContext type was printed on a thread id 1
WebSocketException type was printed on a thread id 1
WebSocketCloseStatus type was printed on a thread id 1
WebProxyScriptElement type was printed on a thread id 1
WebSocketState type was printed on a thread id 1
WebSocketReceiveResult type was printed on a thread id 1
WebSocketMessageType type was printed on a thread id 1
WebUtilityElement type was printed on a thread id 1
WebRequestModulesSection type was printed on a thread id 1
WebRequestModuleElementCollection type was printed on a thread id 1
WebRequestModuleElement type was printed on a thread id 1
---
Parallel LINQ query. The results are being merged on a single thrad
使用AsParallel方法将查询并行化
默认情况下结果会被合并到单个线程中
Time elapsed: 00:00:01.2693944
Press Enter to continue....

示例三

点击查看运行结果
txt
WebClient type was processed on a thread id 3
WebExceptionStatus type was processed on a thread id 1
WebRequestMethods type was processed on a thread id 6
WebException type was processed on a thread id 4
WebClient type was printed on a thread id 3
WebException type was printed on a thread id 4
WebRequestMethods type was printed on a thread id 6
WebExceptionStatus type was printed on a thread id 1
WebPermissionAttribute type was processed on a thread id 4
WebHeaderCollection type was processed on a thread id 3
WebPermission type was processed on a thread id 6
WebProxy type was processed on a thread id 1
WebPermissionAttribute type was printed on a thread id 4
WebPermission type was printed on a thread id 6
WebProxy type was printed on a thread id 1
WebHeaderCollection type was printed on a thread id 3
WebResponse type was processed on a thread id 6
WebRequest type was processed on a thread id 4
WebUtility type was processed on a thread id 1
WebSocket type was processed on a thread id 3
WebUtility type was printed on a thread id 1
WebResponse type was printed on a thread id 6
WebRequest type was printed on a thread id 4
WebSocket type was printed on a thread id 3
WebSocketError type was processed on a thread id 4
WebSocketCloseStatus type was processed on a thread id 1
WebSocketException type was processed on a thread id 3
WebSocketContext type was processed on a thread id 6
WebSocketCloseStatus type was printed on a thread id 1
WebSocketError type was printed on a thread id 4
WebSocketException type was printed on a thread id 3
WebSocketContext type was printed on a thread id 6
WebSocketMessageType type was processed on a thread id 1
WebSocketReceiveResult type was processed on a thread id 4
WebSocketState type was processed on a thread id 3
WebProxyScriptElement type was processed on a thread id 6
WebSocketMessageType type was printed on a thread id 1
WebSocketReceiveResult type was printed on a thread id 4
WebSocketState type was printed on a thread id 3
WebProxyScriptElement type was printed on a thread id 6
WebUtilityElement type was processed on a thread id 6
WebRequestModuleElementCollection type was processed on a thread id 4
WebRequestModuleElement type was processed on a thread id 1
WebRequestModulesSection type was processed on a thread id 3
WebRequestModuleElementCollection type was printed on a thread id 4
WebRequestModuleElement type was printed on a thread id 1
WebUtilityElement type was printed on a thread id 6
WebRequestModulesSection type was printed on a thread id 3
---
Parallel LINQ query. The results are being processed in parallel
使用ForAll方法将打印操作和查询操作放到了同一个线程,跳过了结果合并的步骤
Time elapsed: 00:00:00.9943332
Press Enter to continue....

示例四

点击查看运行结果
txt
WebRequestMethods type was processed on a thread id 1
WebRequestMethods type was printed on a thread id 1
WebClient type was processed on a thread id 1
WebClient type was printed on a thread id 1
WebException type was processed on a thread id 1
WebException type was printed on a thread id 1
WebExceptionStatus type was processed on a thread id 1
WebExceptionStatus type was printed on a thread id 1
WebHeaderCollection type was processed on a thread id 1
WebHeaderCollection type was printed on a thread id 1
WebPermissionAttribute type was processed on a thread id 1
WebPermissionAttribute type was printed on a thread id 1
WebPermission type was processed on a thread id 1
WebPermission type was printed on a thread id 1
WebProxy type was processed on a thread id 1
WebProxy type was printed on a thread id 1
WebRequest type was processed on a thread id 1
WebRequest type was printed on a thread id 1
WebResponse type was processed on a thread id 1
WebResponse type was printed on a thread id 1
WebUtility type was processed on a thread id 1
WebUtility type was printed on a thread id 1
WebSocket type was processed on a thread id 1
WebSocket type was printed on a thread id 1
WebSocketCloseStatus type was processed on a thread id 1
WebSocketCloseStatus type was printed on a thread id 1
WebSocketContext type was processed on a thread id 1
WebSocketContext type was printed on a thread id 1
WebSocketError type was processed on a thread id 1
WebSocketError type was printed on a thread id 1
WebSocketException type was processed on a thread id 1
WebSocketException type was printed on a thread id 1
WebSocketMessageType type was processed on a thread id 1
WebSocketMessageType type was printed on a thread id 1
WebSocketReceiveResult type was processed on a thread id 1
WebSocketReceiveResult type was printed on a thread id 1
WebSocketState type was processed on a thread id 1
WebSocketState type was printed on a thread id 1
WebProxyScriptElement type was processed on a thread id 1
WebProxyScriptElement type was printed on a thread id 1
WebRequestModuleElement type was processed on a thread id 1
WebRequestModuleElement type was printed on a thread id 1
WebRequestModuleElementCollection type was processed on a thread id 1
WebRequestModuleElementCollection type was printed on a thread id 1
WebRequestModulesSection type was processed on a thread id 1
WebRequestModulesSection type was printed on a thread id 1
WebUtilityElement type was processed on a thread id 1
WebUtilityElement type was printed on a thread id 1
---
Parallel LINQ query, transformed into sequential.
使用AsSequential方法将PLINQ查询以顺序方式执行
运行结果同第一个示例完全一样
Time elapsed: 00:00:03.9615061
Press Enter to continue....