zoukankan      html  css  js  c++  java
  • 黄聪:C# 使用线程你可能不知道的问题

    前些天有个朋友问我,他在做WinForm 程序,其中使用到了线程。

     当时我听到线程我就懵了,其一 我很久都没有使用过线程了,其二 线程说实话有些难,其三 遇到线程稀奇古怪的问题我真的很难回答。当时我就模糊的回答了他一下,就这样勉强的回避了他的问题,因为之前我总是不断的去回避线程这个问题,你说线程简单也简单,你说难也难。与我来说线程真的是个麻烦事,我一直都是采用回避政策,今天我查阅了之前自己写过的一个WinForm 扫雷游戏,其中就使用过线程。

    1.在WinForm 中使用线程和定时器控制动画

      

      看到上面的这张图,其实他是一个动画效果,左边的字幕是从下向上不断移动的,而且在不间断的重复这个动作。在进行WinForm开发的时候,我们不能像Web程序一样使用一个Marquee 标签 是字幕移动,这里我们需要的是坐标定位,而且是绝对定位,让字幕坐标不断的改变,从而产生动画效果。

      

    2.线程使用带来的后果

      至于效果怎么实现的我们不多说,今天的主题是线程使用的后果。

      

      看看这个扫雷的界面,以前费了九牛二虎之力弄出来这样一个东西,整天埋头于算法当中。当时学习的时候就凭着自己的一股热情,使用线程啊,线程多好,可以让WinForm 产生动画效果。后来我发现自己错了,真的错了。

      

      最头疼的事情来了,大家一定都见过这个问题,我可以说只要使用过线程的几乎到见过这个问题。原因是什么,线程。最大恶极的线程,就是因为我在这个扫雷程序中使用了线程,最终导致了这样的问题。每次在程序重新启动的时候就会出现这个问题,该线程已经被添加到系统线程中,却无法查杀。郁闷啊

    3.线程介绍

      我查阅了 资料,让我看到了醒目的一行字:

      

    线程            必须要了解,执行.NET应用的线程实际上仍然是Windows线程。但是,当某个线程被CLR所知时,我们将它称为受托管的线程。具体来说,由受托管的代码创建出来的线程就是受托管的线程。如果一个线程由非托管的代码所创建,那么它就是非托管的线程。不过,一旦该线程执行了受托管的代码它就变成了受托管的线程。必须要了解,执行.NET应用的线程实际上仍然是Windows线程。但是,当某个线程被CLR所知时,我们将它称为受托管的线程。具体来说,由受托管的代码创建出来的线程就是受托管的线程。如果一个线程由非托管的代码所创建,那么它就是非托管的线程。不过,一旦该线程执行了受托管的代码它就变成了受托管的线程

      一个受托管的线程和非托管的线程的区别在于,CLR将创建一个System.Threading.Thread类的实例来代表并操作前者。在内部实现中,CLR将一个包含了所有受托管线程的列表保存在一个叫做ThreadStore地方。

      上面的字段文字是从其他地方贴过来的。但是让我明白了一件事,.net 的线程其实仍然是Windows 线程。说道这里我心里不尽不寒而栗,Windows 线程最可怕的名词。难道真的没有解决办法了,难道这个这个线程真的无法关掉。

    4.查看任务管理器

      

      打开任务管理器,上面显示很多没有关闭的线程,而且都是关于这个扫雷程序的,天啊。如果这样岂不是会吃掉所有的内存。于是乎,看看下面的代码

    代码
     1 public void ExitProcess ()
     2         {
     3 
     4             Process[] proc = Process.GetProcesses();
     5             for (int j = 0; j < proc.Length; j++)
     6             {
     7                 if (proc[j].ProcessName == "MineSweeping")
     8                 {
     9                     proc[j].Kill();
    10                 }
    11             }
    12 
    13         }

      Process 这个类就是我的救星啦,他可以获得系统中的进程。只要在我关闭程序的时候每次都对这个进程进行查杀。遇到你 我就kill

      当我再次运行这个程序的时候,哈哈这个问题终于解决了。

    5.另外一个效果

       

      对比两者 的效果,这事WinForm 窗体退出程序的时候的效果,逐渐退出。

      

    代码
     1 public void ExitApplication()
     2         {
     3             if (this.panelButton.Controls!=null)
     4             {
     5                 this.panelButton.Controls.Clear();
     6             }
     7 
     8             for(int i=0;i<1000;i++)
     9             {
    10                 if(this.Opacity<0.1)
    11                 {
    12                     this.ExitProcess();
    13                     Application.Exit();
    14                 }
    15                 this.Opacity=this.Opacity-0.004;
    16                 Thread.Sleep(20);
    17             }
    18             this.main.Dispose();
    19         }

    其实这个效果就是控制窗体的透明度,渐变效果。这也是线程哦。

  • 相关阅读:
    日期时间工具类
    jQuery 使用attr()方式设置 checked 失效原因及解决方法
    vue总结
    【笔记】golang中使用protocol buffers的底层库直接解码二进制数据
    【笔记】对golang的大量小对象的管理真的是无语了……
    【记录一个问题】thanos receiver在更换tsdb文件后,内存并未显著下降
    【笔记】论文阅读:《Gorilla: 一个快速, 可扩展的, 内存式时序数据库》
    【分享】thanos receiver的grafana报表配置
    【采坑小计】thanos receiver的官方文档中,并未说明tsdb落盘的配置方式
    【记录一个问题】thanos receiver在tsdb切换期间,导致remote write接口失败增加
  • 原文地址:https://www.cnblogs.com/huangcong/p/1698475.html
Copyright © 2011-2022 走看看