谈谈C#多线程开发:并行、并发与异步编程

本文探讨了C#中多线程开发的重要性,推荐使用Task和并行编程,避免使用Thread、ThreadPool等传统技术。详细介绍了Task的使用,如何实现并行计算,线程同步的策略,如ManualResetEvent和AutoResetEvent,以及异步编程模型(await、async)的应用。同时,文章还讨论了多线程环境下的数据安全问题和异常处理,强调正确处理异常和使用线程安全的容器如ConcurrentDictionary的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

现代程序开发过程中不可避免会使用到多线程相关的技术,之所以要使用多线程,主要原因或目的大致有以下几个:

1、 业务特性决定程序就是多任务的,比如,一边采集数据、一边分析数据、同时还要实时显示数据;

2、 在执行一个较长时间的任务时,不能阻塞UI界面响应,必须通过后台线程处理;

3、 在执行批量计算密集型任务时,采用多线程技术可以提高运行效率。

传统使用的多线程技术有:

  1. Thread & ThreadPool
  2. Timer
  3. BackgroundWorker

目前,这些技术都不再推荐使用了,目前推荐采用基于任务的异步编程模型,包括并行编程和Task的使用。

 

一、使用Task:

大部分情况下,多线程的应用场景是在后台执行一个较长时间的任务时,不能阻塞界面响应,同时,任务还是可以取消的。

下面我们实现一个简单的示例功能:用户点击Start按钮时启动一个任务,任务执行过程中通过进度条显示任务进度,点击Stop按钮结束任务。

 View Code

 这个代码写的中规中矩,没什么特别的地方,仅仅是用Tsak取代了早期经常采用的Thread、ThreadPool等,虽然Task内部也是对ThreadPool的封装,但仍然建议尽量采用TASK来实现多任务。

 注意:虽然可以通过代码强行结束一个任务,但强烈建议不要这样做,应该给它一个通知让其自己结束。

 

二、并行编程:

目标:通过一个计算素数的方法,循环计算并打印出10000以内的素数。

计算一个数是否素数的方法:

 View Code

如果不采用并行编程,常规实现方法:

            for (int i = 1; i <= 10000; i++)
            {
                bool b = IsPrimeNumber(i);             
                Console.WriteLine($"{i}:{b}");
            }

采用并行编程方法:

           Parallel.For(1, 10000, x=> 
           {
                bool b = IsPrimeNumber(x);              
                Console.WriteLine($"{i}:{b}");
            });

运行程序发现时间差异并不大,主要原因是瓶颈在打印控制台上面,去掉打印代码,只保留计算代码,就可以看出性能差异。

Parallel实际是通过线程池进行任务的分配,线程池的最小线程数和最大线程数将影响到整个程序的性能,需要合理设置。(最小线程默认为8。)

            ThreadPool.SetMinThreads(10, 10);
            ThreadPool.SetMaxThreads(20, 20);

 按照上述设置,假设线程任务耗时比较长不能很快结束。在启动前面10个线程时速度很快,第10~20个线程就比较慢一点,大约0.5秒,到达20个线程以后,如果前期任务没有结束就不能继续分配任务了。

和Task类似,Parallel类仍然是对ThreadPool的封装,但Parallel有一个优势,它能知道所有任务是否完成,如果采用线程池来实现批量任务,我们需要自己通过计数的方式确定所有子任务是否全部完成。

 Parallel类还有一个ForEach方法,使用和For类似,就不重复描述了。

三、 线程(或任务)同步

有时我们需要通知一个任务结束,或一个任务等待某个条件进入下一个状态,这就需要用到任务同步的技术。

一个比较简单的方法就是定义一个变量来表示状态。

      private volatile bool CancelWork = false;

后台任务可以轮询该变量进行判断:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值