• C# 多线程(一)


    一直没有系统学习过C# 的多线程,今天跑一个图片迁移的小程序时,发现速度奇慢,想着要是改成多线程的应该就会好很多,但是改造过程总是出现奇奇怪怪的错误,怪只怪基础没打好,下决心要从基础开始了解多线程。

    1.多线程实现方式private void btnThreadTest_Click(object sender, EventArgs e)        {

                try
                {
              
                   // CreatThreadByNewThread();
                   // CreatThreadByThreadPool();
                    CreatThreadByTask();
                    CreatThreadByDelegate();
                    for (var i = 0; i < 10000; i++)
                    {                  
                        Console.Write(i + "x");
                    }
                  
                }
                catch (Exception)
                {
    
                    throw;
                }
            }
    
     /// <summary>
            /// 直接new一个Thread
            /// </summary>
            public void CreatThreadByNewThread() {
                try
                {
                    //1.直接new一个新线程
                    //Thread firstThread = new Thread(new ThreadStart(ThreadTest1));//无参线程
                    Thread firstThread = new Thread(new ParameterizedThreadStart(ThreadTest1));
                    firstThread.Start("线程参数");
                    firstThread.Join();//同下文中task的wait
                    Thread.Sleep(1);//暂停当前线程一段时间,单位微秒 ,Thread.Sleep(0)立即放弃这个线程的时间片,主动交出CPU给其他线程           
                }
                catch (Exception)
                {
    
                    throw;
                }
            }
            //使用线程池
            public void CreatThreadByThreadPool() {
                try
                {
                    //2.线程池
                    ThreadPool.UnsafeQueueUserWorkItem(ThreadTest1, "线程参数");
                }
                catch (Exception)
                {
    
                    throw;
                }
            }
    
            /// <summary>
            /// 使用task
            /// </summary>
            public void CreatThreadByTask()
            {
                try
                {
                    //3.task执行
                    Task<int> t1 = new Task<int>(n => ThreadTest2((object)n), "线程参数");
                    t1.Start();
                    t1.Wait();//等待线程执行完成                
                    Task tend = t1.ContinueWith(task => Console.WriteLine("Thread result is {0}", t1.Result));
    
                }
                catch (Exception)
                {
    
                    throw;
                }
            }        

      

    //使用委托异步执行
            public void CreatThreadByDelegate() {
                try
                {
            //4. 委托异步执行,委托有多种声明方
    		//Delegate 至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型
    		//Func可以接受0个至16个传入参数,必须具有返回值 func<string,int> fun_t=ThreadTest2
    		//Action可以接受0个至16个传入参数,无返回值
     		//Predicate只能接受一个传入参数,返回值为bool类型
             
       		MyDelegate mydelegate = new MyDelegate(ThreadTest2);
    		IAsyncResult result = mydelegate.BeginInvoke("线程执行参数", ThreadCallback, "线程回调参数");//线程执行完成后自动执行的回调函数
            	int resstr = mydelegate.EndInvoke(result);//会等待线程执行完成后执行
            	Console.WriteLine("Thread result is {0}", resstr);
                }
                catch (Exception)
                {
    
                    throw;
                }
            }
    

      

    2.多线程数据安全。

      对于多线程共享的数据,且有线程对共享数据存在写操作时,需要添加独占锁,lock,将线程对改共享数据操作部分加锁,下面中done就是共享数据

    static readonly object locker = new object();
     lock (locker)
            {
                 if (!done)
                 {
                    Console.WriteLine("Done");
                    done = true;
                 }
           }
    

      当某一个线程访问独占锁时,其他线程会阻塞等待,独占锁的释放,

      有一个批量下载上传的任务,当使用到上面介绍的线程池来做上传处理时,发现如果不对线程池做控制,则很可能出现死锁的情况,线程池中一部分线程都阻塞在IO上,因此设置线程池线程的数量

       ThreadPool.SetMinThreads(2, 1);//参数1:线程池根据需要穿件的新的最小工作程序线城市数,参数2:新的最小空闲异步I/O线程数
       ThreadPool.SetMaxThreads(5, 10);//第一个参数是线程池中辅助线程的最大数目,第二个参数是线程池中异步I/O线程的最大数目

      下面的方法能够查询到还有多少线程在运行,适合于查询是否有线程死锁

             //检索由 System.Threading.ThreadPool.GetMaxThreads(System.Int32@,System.Int32@) 方法返回的最大线程池线程数和当前活动线程数之间的差值。        
            //参数:
            //workerThreads:
            //可用辅助线程的数目。      
            //completionPortThreads:
            //可用异步 I/O 线程的数目。
             ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
    
         //检索由 System.Threading.ThreadPool.GetMaxThreads(System.Int32@,System.Int32@) 方法返回的最大线程池线程数和当前活动线程数之间的差值。        
         // 参数:
         //workerThreads:
         //可用辅助线程的数目。  
         //completionPortThreads:
         //可用异步 I/O 线程的数目。
         ThreadPool.GetMaxThreads(out maxWordThreads, out completionPortThreads);
                        
    

      

    参考文章:http://www.cnblogs.com/jackson0714/p/5100372.html

         http://www.cnblogs.com/luxiaoxun/p/3280146.html

  • 相关阅读:
    《基于CMMI的软件工程及实训指导》第一章读书心得
    第一个微信小项目
    自己设计大学排名-数据库实践
    第一次爬虫和测试
    预测球队比赛成绩
    自己的第一个网页
    科学计算和可视化
    第一个微信小项目
    数据库实际
    第一个爬虫和测试
  • 原文地址:https://www.cnblogs.com/huanglin101/p/6430102.html
Copyright © 2020-2023  润新知