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

发布时间 - 2026-01-11 02:46:23    点击率:

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

方案一:

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

 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;


# C#  # 多线程  # 线程控制  # C#多线程基础知识汇总  # C# 多线程编程技术基础知识入门  # 基于C#实现的轻量级多线程队列图文详解  # C#中的多线程小试牛刀  # C#中的多线程超时处理实践方案  # C#多线程之Semaphore用法详解  # C# 文件上传下载(Excel导入  # 多线程下载)功能的实现代码  # C#多线程及同步示例简析  # C#多线程之Thread类详解  # 深入了解c#多线程编程  # 挂起  # 死锁  # 过程中  # 的是  # 信号量  # 已被  # 将其  # 微软  # 请使用  # 将被  # 停下来  # 大家分享  # 具体内容  # 正常运行  # 判断是否  # 全局变量  # 互斥  # gt  # btn_Resume_Click 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  ChatGPT 4.0官网入口地址 ChatGPT在线体验官网  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  专业商城网站制作公司有哪些,pi商城官网是哪个?  网站页面设计需要考虑到这些问题  jQuery中的100个技巧汇总  linux写shell需要注意的问题(必看)  利用vue写todolist单页应用  Laravel如何创建自定义Artisan命令?(代码示例)  猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】  ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  Laravel如何升级到最新版本?(升级指南和步骤)  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  如何在建站之星绑定自定义域名?  Android滚轮选择时间控件使用详解  如何在万网开始建站?分步指南解析  高端建站如何打造兼具美学与转化的品牌官网?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  如何在Windows 2008云服务器安全搭建网站?  魔毅自助建站系统:模板定制与SEO优化一键生成指南  Laravel怎么清理缓存_Laravel optimize clear命令详解  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  iOS验证手机号的正则表达式  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  微信小程序 HTTPS报错整理常见问题及解决方案  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  如何在阿里云购买域名并搭建网站?  Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Laravel如何创建自定义中间件?(Middleware代码示例)  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  如何在宝塔面板中创建新站点?  音乐网站服务器如何优化API响应速度?  Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】  Laravel怎么判断请求类型_Laravel Request isMethod用法  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  微信推文制作网站有哪些,怎么做微信推文,急?  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  网站制作大概要多少钱一个,做一个平台网站大概多少钱?