zoukankan      html  css  js  c++  java
  • c# 线程浅析(代理 、Invoke、Lock)

    前言:本来想根据自己的经验总结一下c#线程相关的知识点, 写之前看了一些其他人的博客,发现自己也就掌握了不到三分之一。。。。希望通过这次的博客将自己的知识点补充一下,写出更直白的博客和初学者分享。

    这是我参考的博客地址:http://www.cnblogs.com/miniwiki/archive/2010/06/18/1760540.html  。

    这个是他参考的英文原著地址:http://www.albahari.com/threading/

    原博客介绍的可以说深入浅出,鞭辟入里。不过我想写出更适合小白的,直接拿去就可以用到程序里的博客。

    一. 什么是线程(知道下面几点有助于了解)

    1. 一个CPU同一时间只能做一件事,不过它处理信息太快了,甚至我们使用它的时候,把它分成了很多的时钟周期(就是很短的时间间隔),再去把这些之间间隔分配个不同的应用,它也能很顺畅的完成处理。就好像它能同时处理很多事一样,我们根据这一点,就可以进行多线程,和多进程编程了。

    2.进程是资源分配的基本单位。我们创建一个程序,默认是一个进程的,这个进程中包含了一个线程(主线程)。现在我们要在这个基础上再去进行创建新的线程。(很多时候需要这样)

    3.进程中的线程,可以共享进程中的资源。

    4.线程是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。

    二.为什么要开启新的线程

     有很多时候主线程处理数据消耗太多时间,导致鼠标不能用,程序看起来卡住了。这时候,我们可以把消耗时间的事放到一个单独的线程里,让主线程轻松起来。

    三. 多线程的使用

    1.目标

    在主线程中开启一个线程,线程传回数据在主窗体中的文本框中显示。

     下面是所有的代码,其中包括了代理 、Invoke、Lock,的使用。这个小的例子就可以帮助你开始使用线程了。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace 线程浅析
    {
         //创建SetValue的委托
        public delegate void SetValueDel(string str,object obj);
    
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                Thread.CurrentThread.Name = "MainThread";
            }
    
            //开启一个线程
            private void btnStart_Click(object sender, EventArgs e)
            {
                //将委托的方法和主窗体传过去
                NEWThreadClass threadOneClass = new NEWThreadClass(SetValue, this);
    
                Thread TheThreadOne = new Thread(threadOneClass.threadOne);//不需要ThreadStart()也可以
    
                TheThreadOne.Name = "TheThreadOne";//给线程命名,方便调试。这行代码可以省略。
    
                //让线程变为后台线程(默认是前台的),这样主线程结束了,这个线程也会结束。要不然,任何前台线程在运行都会保持程序存活。
                TheThreadOne.IsBackground = true;
                TheThreadOne.Start();
            }
    
            //给文本框赋值
            private void SetValue(string str, object obj)
            {
                //lock里面的代码同一个时刻,只能被一个线程使用。其它的后面排队。这样防止数据混乱。
                lock (obj)
                {
                    this.txtReturnValue.Text = this.txtReturnValue.Text + str;
                }
            }
        }
    
        //建一个类,模拟实际使用情况
        public class NEWThreadClass
        {
            //接收主窗体传过来的委托方法。
            public SetValueDel setValueDel;
    
            //接收主窗体
            public Form form;
    
            //用于告诉主线程中锁,是哪一个线程调用的。
            static object locker = new object();
    
            public NEWThreadClass(SetValueDel del ,Form fom)
            {
                this.setValueDel = del; 
                this.form = fom;
            }
            //第一个线程,给主线程创建的控件传值。
            public  void threadOne()
            {
                //这里获取线程的名字
                string threadName = Thread.CurrentThread.Name;
                try
                {
                    while (true)
                    {
                        //告诉主线程,我要更改你的控件了。
                        this.form.Invoke((EventHandler)(delegate
                        {
                            //如果在这里使用Thread.CurrentThread.Name 获取到的是主线程的名字。
                            setValueDel(threadName + " :Hello!", locker);//给文本框传值,“自己的名字:Hello!”。
                        }));
                        Thread.Sleep(3 * 1000);//太累了 ,休息三秒。。。。
                    }
                }
                catch (Exception ex)
                { }
            }
        }
    }
     

     

        

          

  • 相关阅读:
    PHP
    linux文件分割(将大的日志文件分割成小的)
    centos安装ssdb
    SSDB 数据库如何换用 rocksdb 引擎?
    A PHP extension for Facebook's RocksDB
    看电影有感
    视频格式(转的豆瓣)
    7月7号项目讲解总结
    java注解Annotation
    xml的解析
  • 原文地址:https://www.cnblogs.com/Cui-Shi-Yu/p/5737940.html
Copyright © 2011-2022 走看看