进程:每一个应用程序都可以看做是一个进程。
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;
}
加上界面,加上灯光效果。一个骗钱偏色的游戏就这么诞生了,所以一定要戒赌,戒掉游戏。原理如上。