C#多线程之线程控制详解

作者:云梦鸿 时间:2022-02-04 17:51:44 

本文为大家分享了C#多线程之线程控制,供大家参考,具体内容如下

方案一:

调用线程控制方法.启动:Thread.Start();停止:Thread.Abort();暂停:Thread.Suspend();继续:Thread.Resume();

C#多线程之线程控制详解


private void btn_Start_Click(object sender, EventArgs e)
   {
     mThread.Start(); // 开始
   }

private void btn_Stop_Click(object sender, EventArgs e)
   {
     mThread.Abort(); // 终止
   }

private void btn_Suspend_Click(object sender, EventArgs e)
   {
     mThread.Suspend(); // 暂停
   }

private void btn_Resume_Click(object sender, EventArgs e)
   {
     mThread.Resume(); // 继续
   }

线程定义为:


mThread = new Thread(() =>
     {
       try
       {
         for (int j = 0; j < 20; j++)
         {
           int vSum = 0;
           this.textBox1.Text += "--->";
           for (int i = 0; i < 100000000; i++)
           {
             if (i % 2 == 0)
             {
               vSum += i;
             }
             else
             {
               vSum -= i;
             }
           }
           this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
           Thread.Sleep(1000);
         }
       }
       catch (ThreadAbortException ex)
       {
         Console.WriteLine("ThreadAbortException:{0}", ex.Message);
       }
     });

值得注意的是: 通过 Thread.Abort() 停下来的线程(或自行运行结束的线程),都无法直接通过 Thread.Start() 方法再次启动,必须重新创建一个线程启动。

所以,“开始按钮”事件应为:


private void btn_Start_Click(object sender, EventArgs e)
   {
     // 定义线程
     mThread = new Thread(() => // Lambda 表达式
     {
       try
       {
         for (int j = 0; j < 20; j++)
         {
           int vSum = 0;
           this.textBox1.Text += "--->";
           for (int i = 0; i < 100000000; i++)
           {
             if (i % 2 == 0)
             {
               vSum += i;
             }
             else
             {
               vSum -= i;
             }
           }
           this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
           Thread.Sleep(1000);
         }
       }
       catch (ThreadAbortException ex)
       {
         Console.WriteLine("ThreadAbortException:{0}", ex.Message);
       }
     });

mThread.Start(); // 开始
   }

此外,对于 Thread.Suspend() 和 Thread.Resume() 方法,微软已经将其标记为过时:

Thread.Suspend has been deprecated.  Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.  http://go.microsoft.com/fwlink/?linkid=14202(Thread.Suspend 已被否决。请使用系统中的其他类线程,如监视器、互斥体、事件和信号量,以同步线程或保护资源。http://go.microsoft.com/fwlink/?linkid=14202)

因为,无法判断当前挂起线程时它正在执行什么代码。如果在安全权限评估期间挂起持有锁的线程,则 AppDoamin 中的其它线程可能被阻止。如果在线程正执行构造函数时挂起它,则 AppDomain 中尝试使用该类的其它线程将被阻止。这样容易发生死锁。

方案二:

在 线程运行过程中 适当的位置(如某个完整的功能/命令后)判断是否要继续线程,再决定线程的命运。

1.定义一个全局变量:


int mTdFlag = 0; // 1:正常运行;2:暂停;3:停止

 2. 定义一个判断方法:


bool WaitForContinue()
   {
     if (this.mTdFlag == 3)
     {
       return false; // 返回false,线程停止
     }
     else if (this.mTdFlag == 2)
     {
       while (mTdFlag != 1)
       {
         Thread.Sleep(200); // 假暂停;停顿时间越短,越灵敏
         if (this.mTdFlag == 3)
         {
           return false; // 返回false,线程停止
         }
       }
     }
     return true; // 返回true,线程继续
   }

3.修改 控制命令 事件:


private void btn_Stop_Click(object sender, EventArgs e)
   {
     this.mTdFlag = 3;
     //mThread.Abort(); // 终止
   }

private void btn_Suspend_Click(object sender, EventArgs e)
   {
     this.mTdFlag = 2;
     //mThread.Suspend(); // 暂停
   }

private void btn_Resume_Click(object sender, EventArgs e)
   {
     this.mTdFlag = 1;
     //mThread.Resume(); // 继续
   }

4.在线程运行过程中适当的位置,判断线程是否继续


mThread = new Thread(() =>
     {
       try
       {
         for (int j = 0; j < 20; j++)
         {
           int vSum = 0;
           this.textBox1.Text += "--->";
           for (int i = 0; i < 100000000; i++)
           {
             if (i % 2 == 0)
             {
               vSum += i;
             }
             else
             {
               vSum -= i;
             }
             if (i % 10000000 == 0)
             {
               this.textBox1.Text += ".";
             }
             if (!WaitForContinue()) // 返回 false 则,停止
             {
               break;
               //return;
             }
           }
           this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
           if (!WaitForContinue()) // 返回 false 则,停止
           {
             break;
             // return;
           }
           Thread.Sleep(1000);
         }
       }
       catch (ThreadAbortException ex)
       {
         Console.WriteLine("ThreadAbortException:{0}", ex.Message);
         this.textBox1.Text += ex.Message + "...";
       }
       finally
       {
         this.textBox1.Text += "线程已结束";
       }
     });

在窗体中,解决跨线程访问问题:在窗体构造函数中添加代码:  Control.CheckForIllegalCrossThreadCalls = false;

来源:http://www.cnblogs.com/CUIT-DX037/p/6955873.html

标签:C#,多线程,线程控制
0
投稿

猜你喜欢

  • Java try()语句实现try-with-resources异常管理机制操作

    2022-02-06 18:29:16
  • Android数据持久化之Preferences机制详解

    2021-09-04 23:42:32
  • java读写oracle的blob字段示例

    2023-12-22 16:19:00
  • Java 散列存储详解及简单示例

    2022-06-30 23:19:52
  • Android自定义wheelview随机选号效果

    2021-09-12 06:36:53
  • 适配android7.0获取文件的Uri的方法

    2022-03-13 17:32:06
  • java利用jacob将word转pdf

    2023-02-05 08:23:03
  • Java Web开发环境配置详解

    2023-03-05 03:32:37
  • Java编程实现打印螺旋矩阵实例代码

    2021-10-16 19:15:14
  • 微信小程序 springboot后台如何获取用户的openid

    2023-01-13 17:07:42
  • Java实现SMS短信通发送手机验证码案例讲解

    2022-05-14 22:37:57
  • Android设备间实现蓝牙(Bluetooth)共享上网

    2023-02-21 14:25:36
  • 安卓11适配攻略抢先看

    2022-05-22 22:39:05
  • 浅谈Java8 判空新写法

    2023-06-21 15:55:08
  • Java利用cors实现跨域请求实例

    2023-02-24 14:57:35
  • Java实现多线程断点下载实例代码(下载过程中可以暂停)

    2021-06-09 18:02:41
  • Java利用File类创建文件的示例代码

    2022-02-09 20:53:54
  • maven工程中jar包瘦身的五种方法

    2023-11-04 05:01:54
  • Java8 Comparator: 列表排序的深入讲解

    2022-12-11 08:30:01
  • Android编程实现屏幕禁止休眠的方法

    2022-11-19 09:21:31
  • asp之家 软件编程 m.aspxhome.com