C#多线程教程与案例

每一个操作系统上运行的应用程序都是一个进程,一个进程(Process)可包含一个或多个线程(Thread)。
线程是操作系统分配处理器时间的基本单位,在进程中可以有多个线程同时执行代码。

打个比喻:进程像是一个公司,公司中的每个员工相当线程,公司想要运转就必须有负责人,负责人相当于主线程。

在这里插入图片描述
单线程:默认情况下,系统应用程序分配一个主线程,该线程执行程序中以Main()方法开始和结束的代码。

多线程:分为 主线程与多个次线程
在这里插入图片描述
用多线程优点:
1、让计算机“同时”多做事情,节约时间
2、多线程可让一个程序“同时”处理多个事情
3、后台运行程序,提高效率,不会使主界面出现,假死与无响应

每个次线程:可分为 前台线程与后台线程
在这里插入图片描述
前台线程:只有所有的前台线程都能关闭才能完成程序关闭。(默认的)

后台线程:只要所有的前台线程结束,后台线程自动结束。
(thread.IsBackground=true)

线程基本操作

       private void button1_Click(object sender, EventArgs e)
        {
            //创建一个线程去执行这个方法
            Thread th = new Thread(Test);
            //标记这个线程准备就绪,可以随时被执行。具体什么时候执行这个线程
            //由cpu决定

            //将线程设置为后台线程
           th.IsBackground = true;
            th.Start();
        }

        private void Test()
        {
            for (int i = 0; i < 1_000_000; i++)
            {
                //Console.WriteLine(i);
                textBox1.Text = i.ToString();
            }
        }

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

在这里插入图片描述
因为textbox是主线程的,新建的次线程无法跨线程去访问它。需要我们需要取消检查,就可以正常访问了。
Control.CheckForIllegalCrossThreadCalls = false;

在这里插入图片描述
错误原因:关闭主线程,textbox文本框已经释放, 次线程还在运行,找不到文本框,所以报错。
解决方法:添加 Abort终止线程

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (th !=null)
            {
                //终止线程
                th.Abort();
            }
        }

注意:线程给 Abort ,不能继续重新 Start了。

Sleep睡眠
单位:毫秒 1秒=1000毫秒
Thread.Sleep(3000) 睡眠3秒

线程常用属性
1、IsAlive:线程一旦开始,IsAlive就为true,否则为false
2、线程结束条件:线程构造函数传入的委托结束了执行
3、线程一旦结束,就无法重新开始了
4、每个线程都有一个Name属性,用于调试
5、Thread.CurrentThread属性,获取当前正在运行的线程

 private void Form1_Load(object sender, EventArgs e)
        {
            string strInfo = string.Empty;
            Thread myThread = new Thread(new ThreadStart(ThreadOut));
            myThread.Start();
            //获取线程相关信息--属性
            strInfo = "线程唯一标识符:" + myThread.ManagedThreadId;
            strInfo = "\n线程名称:" + myThread.Name;
            strInfo = "\n线程状态:" + myThread.ThreadState.ToString();
            strInfo = "\n线程优先级:" + myThread.Priority.ToString();
            strInfo = "\n是否为后台线程:" + myThread.IsBackground;
            richTextBox1.Text = strInfo;
            //方法
            Thread.Sleep(1000);//停顿1秒
            myThread.Abort("退出");//通过主线程阻止新开线程
            myThread.Join(); //等待新开的线程结束
            MessageBox.Show("线程运行结束");
        }

        public void ThreadOut()
        {
            MessageBox.Show("主线程开始运行");
        }

创建线程

 static void Main(string[] args)
        {
            Thread myThread;
            //方法1
            //myThread = new Thread(CreateThread);
            //方法2
            myThread = new Thread(new ThreadStart(CreateThread));
            myThread.Start();
        }

        public static void CreateThread()
        {
            Console.WriteLine("创建线程");
        }
 //Lmada表达式
            new Thread(() =>
            {
                Console.WriteLine("I'm running on another thread!");
                Console.WriteLine("This is so easy");
            }).Start();

SynchronizationContext.Current

        SynchronizationContext _uiSyncContext;
        private void button1_Click(object sender, EventArgs e)
        {
            //未当前UI线程捕获Synchronization Context
            _uiSyncContext = SynchronizationContext.Current;
            new Thread(Work).Start();
            //new Thread()
        }

        void Work()
        {
            //模拟耗时操作
            Thread.Sleep(millisecondsTimeout: 5000);
            UpdateMessage("The answer");
        }
        void UpdateMessage(string message)
        {
            //把委托Marshal给UI线程
            _uiSyncContext.Post(x => textBox1.Text = message, null);

            //调用 Post就相当于调用Dispatch 或 Control 上面的 BeginInvoke方法
            //还有一个 Send方法,它等价于Invoke方法
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值