【C#知识点】线程池

1.线程池的作用

每当启动一个线程都是有消耗的,线程池通过预先创建可回收线程的池来降低这个开销,且能够对线程进行有效调度,使处理器不至于超负荷。

2.如何将代码运行在线程池中:

Task.Run(委托);

示例:

    static void Main(string[] args)
    {
        Console.WriteLine("主线程【{0}】,开始执行",GetCurrentThreadId());

        Task.Run(LogRunningState);
        Task.Run(LogRunningState);
            
        Console.WriteLine("主线程【{0}】,执行完毕",GetCurrentThreadId());

        Console.ReadLine();
    }
        
    /// <summary>
    /// 打印运行状态
    /// </summary>
    private static void LogRunningState()
    {
        var threadTag = Thread.CurrentThread.IsBackground ? "后台线程" : "前台线程";
        var threadId = Thread.CurrentThread.ManagedThreadId;
            
        Console.WriteLine("【{0}】线程【{1}】开始执行",threadTag,threadId);
        Console.WriteLine("【{0}】线程【{1}】执行完毕",threadTag,threadId);
    }

    /// <summary>
    /// 获取当前线程id
    /// </summary>
    private static int GetCurrentThreadId()
    {
        return Thread.CurrentThread.ManagedThreadId;
    }

输出:
在这里插入图片描述
可见,默认状态下,线程池中的线程为后台线程。

3.Task的是什么?

Task代表了一个并发操作,默认使用线程池中的线程来执行操作,在执行Task.Run时将返回一个Task对象。

4.如何获得Task结果?

1.无返回Task直接调用其Wait方法,该Wait方法将阻塞当前线程直至Task完成,示例如下:

 	static void Main(string[] args)
    {
        Console.WriteLine("主线程【{0}】,开始执行",GetCurrentThreadId());

        var task1 = Task.Run(LogRunningState);
        task1.Wait();
        
        var task2 = Task.Run(LogRunningState);
        task2.Wait();
            
        Console.WriteLine("主线程【{0}】,执行完毕",GetCurrentThreadId());
    }
        
    /// <summary>
    /// 打印运行状态
    /// </summary>
    private static void LogRunningState()
    {
        var threadTag = Thread.CurrentThread.IsBackground ? "后台线程" : "前台线程";
        var threadId = Thread.CurrentThread.ManagedThreadId;
            
        Console.WriteLine("【{0}】线程【{1}】开始执行",threadTag,threadId);
        Console.WriteLine("【{0}】线程【{1}】执行完毕",threadTag,threadId);
    }

    /// <summary>
    /// 获取当前线程id
    /// </summary>
    private static int GetCurrentThreadId()
    {
        return Thread.CurrentThread.ManagedThreadId;
    }

输出:
在这里插入图片描述

2.有返回值Task,可直接调用Result,若Task还未执行完毕,则会阻塞当前线程,直至Task执行完毕。示例如下:

	static void Main(string[] args)
    {
        Console.WriteLine("主线程【{0}】,开始执行",GetCurrentThreadId());

        var task1 = Task.Run(() => GetSumOfNumbers(new List<int>() { 1, 2, 3 }));
        task1.Wait();
        var sum=task1.Result;
        
        Console.WriteLine("和为:{0}",sum);
            
        Console.WriteLine("主线程【{0}】,执行完毕",GetCurrentThreadId());
    }

    /// <summary>
    /// 获得数值和
    /// </summary>
    private static int GetSumOfNumbers(List<int> numbers)
    {
        var sum = 0;
        foreach (var number in numbers)
        {
            sum += number;
        }
        
        return sum;
    }

输出:
在这里插入图片描述

5.如何在Task执行完毕后,执行指定内容?

1.调用Task的Continue方法

	static void Main(string[] args)
    {
        Console.WriteLine("主线程【{0}】,开始执行",GetCurrentThreadId());

        var task= Task.Run(()=>GetSumOfNumbers(new List<int>(){1,2,3}));
        task.ContinueWith(LogTaskResult);
            
        Console.WriteLine("主线程【{0}】,执行完毕",GetCurrentThreadId());
        Console.ReadLine();
    }

    /// <summary>
    /// 获得数值和
    /// </summary>
    private static int GetSumOfNumbers(List<int> numbers)
    {
        var sum = 0;
        foreach (var number in numbers)
        {
            sum += number;
        }
        return sum;
    }

    /// <summary>
    /// 打印任务结果
    /// </summary>
    /// <param name="task">任务</param>
    private static void LogTaskResult(Task<int> task)
    {
        Console.WriteLine(task.Result);
    }

输出:
在这里插入图片描述

2.Task执行GetAwaiter()获得一个Awaiter对象,可通过此对象的GetResult获取Task执行结果和OnCompleted方法传入结束后要执行的逻辑。

	static void Main(string[] args)
    {
        Console.WriteLine("主线程【{0}】,开始执行",GetCurrentThreadId());

        var task= Task.Run(()=>GetSumOfNumbers(new List<int>(){1,2,3}));
        var taskAwaiter = task.GetAwaiter();
        taskAwaiter.OnCompleted(()=>LogNumber(taskAwaiter.GetResult()));
            
        Console.WriteLine("主线程【{0}】,执行完毕",GetCurrentThreadId());
        Console.ReadLine();
    }

    /// <summary>
    /// 获得数值和
    /// </summary>
    private static int GetSumOfNumbers(List<int> numbers)
    {
        var sum = 0;
        foreach (var number in numbers)
        {
            sum += number;
        }
        return sum;
    }

    /// <summary>
    /// 打印数字
    /// </summary>
    /// <param name="number">数字</param>
    private static void LogNumber(int number)
    {
        Console.WriteLine(number);
    }

输出:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值