CSharp中进程与线程入门

进程:每一个应用程序都可以看做是一个进程。

1、进程

在C#中操作进程的类叫做:Process

static void Main(string[] args)
        {
            // 获取当前所有正在运行的进程
            //Process[] pros = Process.GetProcesses();
            //foreach (var item in pros)
            //{
            //    // 关闭所有进程。
            //    // item.Kill();
            //    Console.WriteLine(item);
            //}


            // 通过进程可以打开一些应用程序;
            //Process.Start("calc");
            //Process.Start("mspaint");
            try
            {
                //调用系统默认的浏览器 
                Process.Start("www.baidu.com");
            }
            catch (Exception)  //容错处理 - 用户没有设置默认浏览器时-则使用IE浏览器打开
            {
                // 方式一:
                //Process.Start(@"C:\Program Files\Internet Explorer\iexplore.exe", "http://www.baidu.com");
                //Process.Start(@"C:\Sublime_Text3_Stable_Build_3176_x64_Chs绿色版\Sublime Text\sublime_text.exe", @"C:\Users\futurecloud\Desktop\newnew.txt");
                // 方式二:
                //Process ie = new Process();
                //ie.StartInfo.FileName = @"C:\Program Files\Internet Explorer\IEXPLORE.EXE";
                //ie.StartInfo.Arguments = @"http://www.baidu.com";
                //ie.Start();
                // 打开一个文件
                ProcessStartInfo psi = new ProcessStartInfo(@"C:\Sublime_Text3_Stable_Build_3176_x64_Chs绿色版\Sublime Text\sublime_text.exe",@"C:\Users\futurecloud\Desktop\newnew.txt");
                //ProcessStartInfo psi = new ProcessStartInfo(@"C:\Sublime_Text3_Stable_Build_3176_x64_Chs绿色版\Sublime Text\sublime_text.exe",@"C:\Program Files\Internet Explorer\IEXPLORE.EXE");
                Process p = new Process();
                p.StartInfo = psi;
                p.Start();
            }
        }

打不开文件或者网址,大部分情况,是因为默认打开方式没有指定,所以,需要在第一个参数中,指明你要用哪个软件打开哪个文件。

2、线程

每一个进程都是由多个线程组成的。

多线程的目的就是为了让计算机同时干多件事。节约时间。防止单线程假死状态。

因此启动一个新的线程,把新任务放到新线程中执行。

几个注意事项:

1、为了防止主线程结束,子线程没有跑完,这种情况,将子线程也设置为后台线程;thread.IsBackgroud=true;

2、.Net会检查跨线程访问,默认不允许跨线程的资源互访。可以通过关闭检查来关闭此功能。Control.CheckForIllegalCrossThreadCalls = false;

3、主线程窗口关闭,子线程没有停止,此时通过窗体事件FormClosing来关闭子线程。thread.Abort()。

4、一旦子线程被Abort(),将无法再次重启。

Thread th;

private void button1_Click(object sender, EventArgs e)
{
    //当点击按钮之后让程序做一件复杂的事;如果此时点击关闭窗口,那么就会出现窗口卡住的情况。
    //Test();
    // 造成的原因是,启动程序后,计算机会分配给程序进程一个主线程来执行程序,只给一个。当主线程结束后,程序退出。
    // 但是当我们执行Console.WriteLine();的时候,主线程去打印功能去了。所以,如果此时点击其他控件,那么主线程无法响应。
    // 造成窗体假死现象。这就是单线程造成的问题。只能执行单一任务。并行不可能。
    // 解决方案:再创建一个线程去执行这个方法:
    //Thread th = new Thread(Test); // 如果这么写,只能在函数内被访问,需要全局访问,放在方法以外声明。
    th = new Thread(Test);
    // 标记这个线程准备好了。随时可以被执行。
    //th.Start();  // ==等于Ready。告诉计算机我准备好了,可以执行。何时执行,由CPU决定。

    //在多线程条件下,主线程如果关闭,那么子线没有跑完的情况下。 子线还在跑。
    // 前台线程;后台线程;

    //前台线程:
    //只有所有的前台程序都关闭了,才能完成程序的关闭;

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

    // 默认新创建的线程,都是前台线程。只有所有前台线程都结束,后台才自动结束,完成整个程序的关闭。
    // 所以为了关闭线程,我们将打印线程,设置为后台线程。
    // 将线程设置为后台线程
    th.IsBackground = true;
    
    th.Start();  // ==等于Ready。告诉计算机我准备好了,可以执行。何时执行,由CPU决定。

}

public void Test()
{
    for (int i = 0; i < 200000; i++)
    {
        // 点击【启动】,在【调试】里面找到【窗口】【输出】
        Console.WriteLine(i);

        // 如果执行,下面这命令:
        // 则报错:System.InvalidOperationException:“线程间操作无效: 从不是创建控件“textBox1”的线程访问它。”
        //textBox1.Text = i.ToString();
        // 意思是说,跨线程访问无效。
        // 主线程创建了textBox1,初始化了窗体控件。新线程想要访问主线程中的资源。被拒绝。
        // 在.Net下,是不允许跨线程的访问。.net会自动检查这个跨线程访问。
        // 为此我们可以关闭这个检查功能,来实现跨线程访问。


        // 取消跨线程访问。
        Control.CheckForIllegalCrossThreadCalls = false;
        textBox1.Text = i.ToString();

        //System.ComponentModel.Win32Exception:“创建窗口句柄时出错。”
        // System.InvalidOperationException:“执行 CreateHandle() 时无法调用值 Dispose()。”

        // 如果测试中,点击关闭窗口,会出现如上错误。
        // 原因是因为,主线程关闭释放资源后,子线程还在跑,需要调用主线程资源,此时刚好报错。
        //解决办法:在窗体中有个事件叫FormClosing。重写。
    }
}

private void button2_Click(object sender, EventArgs e)
{
    Form frm2 = new Form();
    frm2.Show();
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // 但你点击关闭窗口的时候,检查新线程是否为null。
    // 如果为null,说明结束,否则手动设置为null。将其关闭停止。
    // 在此检查th。检测不到,所以需要将th声明在上一个函数之外。让类内可访。
    if (th!=null)
    {
        th.Abort();   // 线程被终止。提醒:线程被终止,就无法重新启动。
    }
}

新增:

Thread可以完成类似休眠停止的操作:Thread.Sleep(3000);  // 相当于python中的time.sleep(3000);   // 相当于OpenCV中的cv2.waitKey(3000);  单位:ms。

 

3、线程执行带参数的方法

1、如果线程执行的方法需要参数,那么要求这个参数必须是Object类型。

2、传入的是object类型,但是在函数中,我们可以将它转变为任意类型的数据。

Thread th;
private void button1_Click(object sender, EventArgs e)
{
    th = new Thread(Test);
    th.IsBackground = true;
    th.Start("123");
    // Test();
}

// 1、如果线程执行的方法需要参数,那么要求这个参数必须是Object类型。
private void Test(object s)
{
    // 将object类型转为了string类型。
    string ss = (string)s;
    for (int i = 0; i < 10000; i++)
    {
        Console.WriteLine(i);
    }
}

 

小案例:3个7yaoJiang机

三个label,一个按钮,开始摇奖。暂停。

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

    }
    
    //PlayGame();
}

private void PlayGame()
{
    Random rd = new Random();
    while (b)
    {
        label1.Text = rd.Next(0, 10).ToString();
        label2.Text = rd.Next(0, 10).ToString();
        label3.Text = rd.Next(0, 10).ToString();

    }
}

private void Form1_Load(object sender, EventArgs e)
{
    Control.CheckForIllegalCrossThreadCalls = false;
}

加上界面,加上灯光效果。一个骗钱偏色的游戏就这么诞生了,所以一定要戒赌,戒掉游戏。原理如上。

 


 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值