C#——学习记录——线程

1.为什么要使用多线程,单线程的缺点是什么?

     下面我们用一个窗体程序来进行解释,首先我们创建一个窗体,加入一个按钮和文本框

      

进入按钮单击事件

     

      private void button1_Click(object sender, EventArgs e)
        {
            Test();
        }

     然后写一个Tesr方法来测试

        public void Test()
        {
            for (int i = 0; i <100000; i++)
            {
                Console.WriteLine(i);
            }
        }

    当我们运行,单击按钮时,执行Test()方法,可以在输出窗口中看到输出I的值,当在输出i的值时是无法对窗体进行操作的,只有当test()执行完以后才能对窗体进行操作!

如果窗体能移动,可以将i的值设置大点,然后再运行(设置太大可能会出现等很久的情况。)

注:输出窗口可以在视图菜单中找到

出现这种情况的原因是当运行窗体时,主线程在初始化窗体,当点击按钮,主线程转去执行Test()方法,所以窗体无法移动,只有当主线程输出完以后才能对窗体进行操作。

那么如何去解决这歌问题了,这时就引入了多线程的概念,我们可以创建一个线程去执行Test()方法,是主线程运行窗体,我们使用Thread类来创建新的线程,但是首先要引入Threadl类的命名空间——using System.Threading;

我们使用下面的方法让线程执行Test方法

    官方解释:

    

      //
        // 摘要:
        //     初始化 System.Threading.Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托。
        //
        // 参数:
        //   start:
        //     一个委托,它表示此线程开始执行时要调用的方法。
        //
        // 异常:
        //   T:System.ArgumentNullException:
        //     start 为 null。
        [SecuritySafeCritical]
        public Thread(ParameterizedThreadStart start);
        private void button1_Click(object sender, EventArgs e)
        {
            //创建一个线程去执行这个方法
            Thread th = new Thread(Test);
            //标记这个线程准备就绪了,可以随时被执行,具体什么时候执行,由cpu决定
            th.Start();
        }


    我们用上述方法创建一个新线程来执行Test,这样刚刚单线程带来的困扰就能够成功的解决了

  但是出现了一个新问题,当输出窗口还在输出i的值得时候,我们单击窗体关闭按钮,发现输出窗口依然还在输出i的值,这是为什么呢

这是出现了两个概念:前台线程和后台线程

     前台线程:只有所有的前台线程都关闭才能完成程序关闭。

     后台线程:只要所有的前台线程结束,后台线程自动结束

    默认创建的线程是前台线程

所以我们需要将程序设置成为后台线程

        //利用这个属性来设置线程为后台线程    
        th.IsBackground = true;

现在单击窗体关闭按钮,输出窗口也停止了!

2。多线程的一些方法和属性

     现在我们将ii值输出到文本框里会出现什么呢?

        

     出现了如上的错误:线程间操作无效: 从不是创建控件“textBox1”的线程访问它。

   这是因为新线程要访问主线程创建的资源,跨线程访问所出现的错误

  解决的办法:当我们窗体加载的时候,设置

        private void Form1_Load(object sender, EventArgs e)
        {
            //取消跨线程的访问
            Control.CheckForIllegalCrossThreadCalls = false;
        }

  这样我们就可以在文本框上成功显示i的值了

但是当你关闭窗体按钮时,有可能会出现下面这种情况,这是因为线程由于延迟不会立即关闭,但是当你打点击关闭按钮时,主线程已经关闭了,但是新创建的线程因为延迟没有立即关闭,会继续去访问文本框,所以报出下面的异常

解决的办法是当点击关闭按钮的时候,就去判断线程是否为null,如果不是,则调用Abort方法来停止线程

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //th要写在外面,这样才能够访问到
            if(th!=null)
            {
                th.Abort();
            }
        }

这样就不会出现这个异常了。

但是终止以后的线程不能再重新开始,否则会出现下面这种情况

线程的一些方法:

     Sleep()方法:让当前线程暂停一段时间再执行

     Name:线程名

    CurrentThread:当前线程的引用

 上面的例子只是简单的理解了下线程,线程还有很多东西没有讲到,后面学习了会继续补充!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值