『C#基础』多线程笔记「一」基本说明

基本概念:

  1. 一个程序集一个进程
  2. 一个进程可以有多个线程,且属于同一个程序集
  3. 每一个线程可以视为一个执行流,每一个执行流用于执行一个特定的任务
  4. 各个线程的执行是独立的
  5. 每个程序集都要有一个主线程
  6. 线程使程序能够执行并发处理
  7. 线程共享应用程序的资源
  8. 线程处理解决了吞吐量和响应性的问题

一般用途:

  1. 可以使用线程处理来监视用户输入,执行后台任务,以及处理并发输入流
  2. 辅助线程经常用在服务器应用程序中,以便无需等待前面的请求完成即可响应传入的请求
  3. 辅助线程可用于在桌面应用程序中执行“后台”任务,使主线程(用于驱动用户界面元素)保持对用户操作的响应
  4. 可以用于执行耗时较多的任务或时间要求紧迫的任务,而不必占用主线程

使用好处:

  1. 多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程
  2. 提高了CPU的利用率,就可以直接提高程序的整体执行速度

使用坏处:

  1. 线程开的越多,内存占用越大
  2. 协调和管理代码的难度加大,需要CPU时间跟踪线程
  3. 线程之间对资源的共享可能会产生可不遇知的问题

几个原则:

  1. 尽量少用多线程,而且使用多线程并不意味着程序有多么的高级
  2. 使用辅助线程执行不需要大量占用其他线程所使用的资源的、耗时较多的任务或时间要求紧迫的任务
  3. 在有需要等待的任务时,可以考虑使用多线程,以提高程序运行的效率
  4. 在线程结束时,可以考虑手工释放内存与资源,而不是等待垃圾回收器
  5. 尽量避免使用公共资源,以减少数据冲突的可能
  6. 对每个线程的运行都要严格监控

几个说明:

  1. 主要的命名空间:System.ThreadingSystem.Threading.Tasks
  2. 主要使用的方法:threadObject.Start()threadObject.Join()threadObject.Sleep(<毫秒>)threadObject.Abort()threadObject.Suspend()threadObject.Resume()
  3. 实例化一个线程对象,需要使用某一个实例的方法作为传入参数
  4. 可以使用Thread.CurrentThread来设置当前线程的一些属性(如:名称等)

操纵线程:

  1. 创建线程:线程在实例化的时候,需要传递一个ThreadStart委托或ParameterizedThreadStart委托(我在式样代码中直接就传了个方法…),传入的委托要包含新线程调用的方法。
  2. 启动线程:使用Start()方法来启动某一个线程对象(调用Start方法之后,并不一定马上就会执行线程中的方法,因为线程的执行是伪并发的),且不可以重复调用某一线程对象的Start方法,不然会引发异常(ThreadStartException)。一旦调用Start方法之后,就不必保持对线程对象的引用了,这个线程会一直执行,直到结束。
  3. 传递数据:可以给被调用的类的构造函数作一定的处理,用于接收初始化数据。还可以在初始化的时候,传入一个委托对象,用于接收回调方法。
  4. 休眠:线程可以通过Sleep方法来进行休眠,这样就可以在休眠的时间段内,把资源让给其他线程去执行。
  5. 中断线程:所谓的中断,不是指中断线程的执行(中断执行可以使用Sleep方法),而是指中断等待状态。可以使用Interrupt执行中断休眠等待操作,如果此时线程正处于休眠等待状态,则引发一个异常ThreadInterruptException,我们可以针对这个异常进行适当的操作。适当的处理这个方法,可以让线程脱离等待状态、让处理阻止线程执行的问题等。
  6. 销毁线程:我们可以使用Abort方法来永久性的停止一个线程(所谓的永久性,其实也是在被线程执行的方法中引发一个异常ThreadAbortException,然后通过捕获这个异常来进行一些操作,当然,我们也可以调用回当前的方法,从而实现永不可被手动销毁)。
  7. 线程调度:我们可以给线程的Priority属性设置值(优先级),从而实现对线程的调度。线程一共有五个优先级,从低到高为ThreadPriority.Lowest、ThreadPriority.BelowNormal、ThreadPriority.Normal、ThreadPriority.AboveNormal、ThreadPriority.Highest
  8. 取消线程(NET 4.0 中加入):可以使用取消标记来取消线程。这个标记不是在Thread中内置的,而是通过使用ParameterizedThreadStart委托的Thread构造函数将一个标记传递给线程过程。

式样代码:

操作类using System;
using System.Threading;

namespace csdemo.basic.ThreadsDemo
{
    public class ThreadBaseDemo
    {
        public void operatThread()
        {
            #region 供给线程调用的对象
            WorkerClass workerA = new WorkerClass(); 
            workerA.WorkerName = "Aaron";
            workerA.WorkName = "Coding";
            workerA.Times = 10;
            WorkerClass workerB = new WorkerClass();
            workerB.WorkerName = "Skyler";
            workerB.WorkName = "Sleeping";
            workerB.Times = 10;
            #endregion

            #region 线程操作相关
            // 实例化线程对象
            Thread workAThread = new Thread(workerA.Do);
            workAThread.Name = "workAThread";
            Thread workBThread = new Thread(workerB.Do);
            workBThread.Name = "workBThread";
            Console.WriteLine("Operate Thread: Starting worker thread...");
            // 开始线程
            workAThread.Start();
            workBThread.Start();

            // 对当前线程实行休眠一毫秒操作
            // 这里是对当前代码所在的线程进行的操作,不会影响到其他线程
            // Thread.Sleep(1);

            /*
             * 这个操作是用于停止线程调用的对象方法的分行;
             * 通过在实调用对象中,创建一个bool类型的变量来监视停止状态;
             * 在主线程中,通过设置辅助线程的监视变量的值来控制线程的停止行为;
             * 需要注意的是,这种方法只能够用于停止线程的执行,而无法让被停止的线程继续执行。
             */
            // workerA.RequestStop();

            /* 强行执行一个线程,直到结束为止;
             * 这个操作会阻塞其他在当前里程中执行的线程,也就是说让当前进程中的其他线程都给这个线程让路;
             * 
             * 由于Thread是使用方法作为实例化方法的,所以还是要在操作类中加入一个bool类型的变量来控制另一个线程的Join操作;            
             */
            workerA.RequestJoin(workBThread);

            Console.WriteLine("Operate Thread: Worker thread joined.");
            #endregion

            Console.WriteLine("Operate Thread: Worker thread is Terminated. ");
        }
        
    }
}

被操作对象using System;
using System.Threading;

namespace csdemo.basic.ThreadsDemo
{
    public class WorkerClass
    {
        #region 属性
        public string WorkerName = "No One";
        public string WorkName = "not working";
        public int Times = 10000;

        // 用于控制线程的停止
        private bool _threadStop = false;
        // 用于控制另一个线程的Join操作
        private bool isOtherJoined = false;
        private Thread otherThread = null;
        #endregion

        // 传入线程的方法
        public void Do()
        {
            Console.WriteLine("Worker thread is started.");

            for (int i = 1; i <= Times; i++)
            {
                if (_threadStop == true)
                    break;

                if (isOtherJoined == true)
                    otherThread.Join();

                Console.WriteLine("{0} is {1} now!", WorkerName, WorkName);
                Thread.Sleep(1000);
            }

            Console.WriteLine("Worker thread is complete.");
        }

        #region 其他操作
        /// <summary>
        /// 这个操作是用于停止线程调用的对象方法的分行;
        /// 通过在实调用对象中,创建一个bool类型的变量来监视停止状态;
        /// 在主线程中,通过设置辅助线程的监视变量的值来控制线程的停止行为;
        /// 需要注意的是,这种方法只能够用于停止线程的执行,而无法让被停止的线程继续执行。
        /// </summary>
        internal void RequestStop()
        {
            Console.WriteLine("{0} Thread: Force stoped");
            _threadStop = true;
        }

        /// <summary>
        /// 强行执行一个线程,直到结束为止;
        /// 这个操作会阻塞其他在当前里程中执行的线程,也就是说让当前进程中的其他线程都给这个线程让路;
        /// 
        /// 由于Thread是使用方法作为实例化方法的,所以还是要在操作类中加入一个bool类型的变量来控制另一个线程的Join操作;
        /// </summary>
        /// <param name="thread">要Join入当前线程的另一个线程对象</param>
        internal void RequestJoin(Thread thread)
        {
            Console.WriteLine("{0} Thread: {1} joined!",this.WorkerName,thread.Name);
            this.otherThread = thread;
            isOtherJoined = true;
        }        
        #endregion
    }
}

带回调的操作类using System;
using System.Threading;

namespace csdemo.basic.ThreadsDemo
{
    public class ThreadBaseDemo
    {
        public void operatThread()
        {
            #region 供给线程调用的对象
            WorkerClass workerA = new WorkerClass("Aaron", "Coding", 20, new ExampleCallback(resultCallback));

            WorkerClass workerB = new WorkerClass("Skyler", "Sleeping", 15, new ExampleCallback(resultCallback));
            #endregion

            #region 线程操作相关
            // 实例化线程对象
            // Thread workAThread = new Thread(workerA.Do);
            Thread workAThread = new Thread(new ThreadStart(workerA.Do));
            workAThread.Name = "workAThread";
            // Thread workBThread = new Thread(workerB.Do);
            Thread workBThread = new Thread(new ThreadStart(workerB.Do));
            workBThread.Name = "workBThread";
            Console.WriteLine("Operate Thread: Starting worker thread...");
            // 开始线程
            workAThread.Start();
            workBThread.Start();

            // 对当前线程实行休眠一毫秒操作
            // 这里是对当前代码所在的线程进行的操作,不会影响到其他线程
            // Thread.Sleep(1);

            /*
             * 这个操作是用于停止线程调用的对象方法的分行;
             * 通过在实调用对象中,创建一个bool类型的变量来监视停止状态;
             * 在主线程中,通过设置辅助线程的监视变量的值来控制线程的停止行为;
             * 需要注意的是,这种方法只能够用于停止线程的执行,而无法让被停止的线程继续执行。
             */
            // workerA.RequestStop();

            /* 强行执行一个线程,直到结束为止;
             * 这个操作会阻塞其他在当前里程中执行的线程,也就是说让当前进程中的其他线程都给这个线程让路;
             * 
             * 由于Thread是使用方法作为实例化方法的,所以还是要在操作类中加入一个bool类型的变量来控制另一个线程的Join操作;            
             */
            // workerA.RequestJoin(workBThread);

            Console.WriteLine("Operate Thread: Worker thread joined.");
            #endregion

            Console.WriteLine("Operate Thread: Worker thread is Terminated. ");            
        }
        static int j = 0;
        public static void resultCallback(int i)
        {
            j++;
            Console.WriteLine("Single thread perform times:\t" + i.ToString() + "\n Total perform times:\t" + j.ToString());
        }

        public static void operateThreadWithState()
        {
            // Supply the state information required by the task.
            ThreadWithState tws = new ThreadWithState(
                "This report displays the number {0}.", 42);

            // Create a thread to execute the task, and then
            // start the thread.
            Thread t = new Thread(new ThreadStart(tws.ThreadProc));
            t.Start();
            Console.WriteLine("Main thread does some work, then waits.");
            t.Join();
            Console.WriteLine(
                "Independent task has completed; main thread ends.");
        }
    }
}


用于回调的委托public delegate void ExampleCallback(int displayTimes);

带回调的被操作类using System;
using System.Threading;

namespace csdemo.basic.ThreadsDemo
{
    public class WorkerClass
    {
        #region 属性
        public string WorkerName = "No One";
        public string WorkName = "not working";
        public int Times = 10000;

        ExampleCallback callback;

        // 用于控制线程的停止
        private bool _threadStop = false;
        // 用于控制另一个线程的Join操作
        private bool isOtherJoined = false;
        private Thread otherThread = null;
        #endregion
        #region 构造函数

        public WorkerClass()
        {
            this.WorkerName = "No One";
            this.WorkName = "not working";
            this.Times = 10000;
        }

        public WorkerClass(string workerName,string workName,int times,ExampleCallback callbackDelegate)
        {
            this.WorkerName = workerName;
            this.WorkName = workName;
            // 回调方法的委托
            this.callback = callbackDelegate;
        }        
        #endregion

        // 传入线程的方法
        public void Do()
        {
            Console.WriteLine("Worker thread is started.");

            for (int i = 1; i <= Times; i++)
            {
                if (_threadStop == true)
                    break;

                if (isOtherJoined == true)
                    otherThread.Join();

                // 回调方法,表面上看是调用一个委托
                // 实质上返回的数据为当前的输出次数               
                if (callback != null)
                    callback(i);

                // Console.WriteLine("{0} is {1} now!", WorkerName, WorkName);
                Thread.Sleep(1000);
            }

            Console.WriteLine("Worker thread is complete.");
        }

        #region 其他操作
        /// <summary>
        /// 这个操作是用于停止线程调用的对象方法的分行;
        /// 通过在实调用对象中,创建一个bool类型的变量来监视停止状态;
        /// 在主线程中,通过设置辅助线程的监视变量的值来控制线程的停止行为;
        /// 需要注意的是,这种方法只能够用于停止线程的执行,而无法让被停止的线程继续执行。
        /// </summary>
        internal void RequestStop()
        {
            Console.WriteLine("{0} Thread: Force stoped");
            _threadStop = true;
        }

        /// <summary>
        /// 强行执行一个线程,直到结束为止;
        /// 这个操作会阻塞其他在当前里程中执行的线程,也就是说让当前进程中的其他线程都给这个线程让路;
        /// 
        /// 由于Thread是使用方法作为实例化方法的,所以还是要在操作类中加入一个bool类型的变量来控制另一个线程的Join操作;
        /// </summary>
        /// <param name="thread">要Join入当前线程的另一个线程对象</param>
        internal void RequestJoin(Thread thread)
        {
            Console.WriteLine("{0} Thread: {1} joined!",this.WorkerName,thread.Name);
            this.otherThread = thread;
            isOtherJoined = true;
        }        
        #endregion
    }
}




参考:

  1. http://msdn.microsoft.com/zh-cn/library/ms173178(v=vs.100).aspx          「MSDN线程处理」
  2. http://msdn.microsoft.com/zh-cn/library/e1dx6b2h.aspx                               「MSDN使用线程」
  3. http://www.cnblogs.com/leslies2/archive/2012/02/07/2310495.html
  4. http://kb.cnblogs.com/page/42528/
  5. http://www.cnblogs.com/huashanlin/archive/2007/07/07/809305.html    「STAThread的含义」
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值