进程与线程

进程:

  是windows系统中的一个基本概念,它包含一个运行着的程序所需要的资源

  进程间是相互独立的,一个进程无法直接访问另一个进程中的数据(除非利用分布式计算方式)

  一个进程运行失败不会影响其它进程的运行

  windows系统利用进程把工作划分为多个独立区域

  进程可以理解为一个应用程序的边界

  C#进程类Process,里面有很多方法,如Start/Kill等

线程:

  是windows系统任务调度的最小单位

  线程是程序执行中的一个执行流

  所有的代码都执行在线程

  同一时刻windows只能执行一个任务,

  但你即QQ又写代码,又执行其它任务,这是因为把这些进程放在了不同的线程中,而CPU运行速度很快,会在这些不同的线程中瞬间切换,你感觉不到,实际上同一时刻只能执行一个线程

  而如果不用线程, 系统运行程序在进程间切换也可以,但进程系统比较庞大,切换起来费时,会让用户体验不好,线程比较小,CPU切换的是进程中的线程,切换速度很快,用户查觉不到

进程与线程 用红砖青砖比喻

  2堆红/青砖 比喻成2个进程

连续把红砖搬完 再搬青砖 叫进程任务 搬红砖时 搬青砖等待 CPU同一时间点只干一件事儿

而线程就是 搬一块红砖 转过来搬块青砖 来回切换 切换时间间隔极短 看起来像同时在干活, 但实际上CPU在同一时刻只干一件事儿

所以搬砖这事儿最优方案就是用线程, 外表同时搬2种砖 而如果不用线程,默认只是进程干活那搬红砖时,青砖只能等待

 

using System;
using System.Threading;
using System.Windows.Forms;

namespace _502线程执行带参数的方法
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //线程实际上过程 : 建方法(有参或无参) 建委托 方法给委托 委托给线程 后台线程 启动 . 简洁一下: 建方法(有参无参) 新线程参数方法名 后台运行 启动
        Thread th = null;//可不写=null
        private void button1_Click(object sender, EventArgs e)
        {
            th = new Thread(Test);//如果Test方法有参数,参数必须是object类型
            th.IsBackground = true;
            th.Start();//这是在后台执行一个无参方法,从这里传方法的参数
        }

        private void Test(object s)//如果Test方法有参数,参数必须是object类型
        {
            string ss = (string)s;//此方法参数只是为了演示,没实际意义
            for (int i = 0; i < 10000; i++)//此方法没有用到窗体控件,比如下面循环值输出到窗体的Lable上,则需要窗体加载事件中的跨线程检查控件关闭的代码
            {
                Console.WriteLine(i);//此还是Form窗体程序,但这控制台好看,那项目属性中调成输出到控制台,则运行时窗口下端可看到,一样的效果
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;//此案例用不上跨线程检查控件,但也加上吧
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //保证运行窗体的主线程关闭时,跑循环的新线程th也关闭,因为有时主线程关了,新线程还在那运行着呢
            if (th!=null)
            {
                th.Abort();
            }
        }
    }
}

 

using System;
using System.Threading;
using System.Windows.Forms;

namespace _503摇奖机线程方法
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            MessageBox.Show("构造方法会在窗体加载时执行么?会的的...,如果加载窗体时需运行,则加到窗体构造方法中或窗体Load事件中都可以...");
        }

        bool b = false;
        private void button1_Click(object sender, EventArgs e)
        {
            if (b == false)
            {
                b = true;
                button1.Text = "停止";
                Thread th = new Thread(PlayGame);
                th.IsBackground = true;
                th.Start();
            }
            else
            {
                b = false;
                button1.Text = "开始";
            }

        }

        private void PlayGame()
        {
            Random r = new Random();
            while (b)
            {
                label1.Text = r.Next(0, 10).ToString();//这些label控件不是在此自定义方法中创建,而是在运行窗体的主线程中创建
                label2.Text = r.Next(0, 10).ToString();
                label3.Text = r.Next(0, 10).ToString();
            }
        }

        //主线程(运行窗体)与新线程(运行死循环)各干各的,即取消跨线程控件检查,否则在没创建控件的方法中调用控件会报错
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
    }
}
View Code

 

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace _109多线程随机抽号
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            label1.Text = string.Empty;
            label2.Text = string.Empty;
            label3.Text = string.Empty;
            File.WriteAllText(@"txt\res.txt", string.Empty);//清除文本文件内容

            Control.CheckForIllegalCrossThreadCalls = false;//取消跨线程间异常检查
        }

        bool b = false;//方法外类下 字段 被所有事件方法调用 用于新线程是否继续执行
        Thread th=null;
        private void button1_Click(object sender, EventArgs e)
        {
            if (b == false)
            {
                b = true;//转之义
                button1.Text = "stop";
                th = new Thread(Test);//新线程 委托调用Test方法 如果委托方法需要参数,请放到下下行th.Start(...)括号中
                th.IsBackground = true;//将线程设置为后台执行,这样主线程结束,新线程也结束
                th.Start();//启动新线程 执行Test程序
            }
            else
            {
                b = false;
                button1.Text = "start";
            }
        }

        void Test()
        {
            Random r = new Random();
            while (b)
            {
                label1.Text = r.Next(0, 10).ToString();
                label2.Text = r.Next(0, 10).ToString();
                label3.Text = r.Next(0, 10).ToString();
            }

            //写文本文件及显示在多行文本框中放这里而非放前面按钮事件中,
            //这里会同步,否则停止时的内容显示在文本框和写到文本文件中的由于时间差对不上
            string str = string.Join(" ", label1.Text.Trim(), label2.Text.Trim(), label3.Text.Trim());
            using (FileStream fsw = new FileStream(@"txt\res.txt", FileMode.Append, FileAccess.Write))
            {
                //byte[] buffer = new byte[1024 * 1024 * 5];                    
                byte[] buffer = Encoding.Default.GetBytes(str + "\r\n");
                fsw.Write(buffer, 0, buffer.Length);
            }
            textBox1.Text += str + "\r\n";

            //以下代码让光标停在多行文本框的最后一行的后面显示最新的行
            //让文本框获取焦点
            this.textBox1.Focus();
            //设置光标的位置到文本尾
            this.textBox1.Select(this.textBox1.TextLength, 0);
            //滚动到控件光标处
            this.textBox1.ScrollToCaret();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //保证运行窗体的主线程关闭时,跑循环的新线程th也关闭,因为有时主线程关了,新线程还在那运行着呢
            if (th != null)
            {
                th.Abort();
            }
        }
    }
}

 

posted @ 2026-06-18 10:43  techNote  阅读(4)  评论(0)    收藏  举报