C#---多线程
来源:互联网 发布:ch341a编程器教程 编辑:程序博客网 时间:2024/05/17 07:02
C#---多线程
线程介绍:前台线程和后台线程。
- 前台线程:只有所有的前台线程都关闭才能完成程序关闭。
- 后台线程:只要所有的前台线程结束,后台线程自动结束。
1、创建一个WINFORM窗体程序,在窗体上添加一个按钮控件和TextBox控件。并为按钮添加一个事件。
修改Form1.cs的代码:
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;namespace 多线程{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Test(); //调用自定义Test()函数 } private void Test()//在控制台打印输出10000个数 { for (int i = 0; i < 10000;i++ ) { Console.WriteLine(i); } } }}
运行结果:可以通过“调试菜单---->窗口---->输出”查看输出结果。
注意:但有一个问题单击按钮后,数字未打印完10000个数字,FORM窗体不能移动。并且未打印完成不能关闭窗体。
(1)单线程问题:点击按钮后,主线程去运行Test()函数进行打印输出。本来主线程是用于窗体的运行。
2、使用多线程方法一
修改Form1.cs的代码:
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; //添加线程命名空间(首先选择,快捷键:alt+shift+F10)namespace 多线程{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //创建一个线程去执行这个方法 Thread th = new Thread(Test); //用线程调用Test()方法 th.Start();//标记这个线程准备就绪了,可以随时被执行。具体什么时候执行这个线程由CPU决定。
th.IsBackground = true; //将线程设置为后台线程 } private void Test() { for (int i = 0; i < 10000;i++ ) { Console.WriteLine(i); } } }}
运行结果:
未设置为后台线程前:单击按钮后,数字未打印完10000个数字,FORM窗体可以进行移动。并且未打印完成可以关闭窗体。但程序依旧在运行。
设置为后台线程后:单击按钮后,数字未打印完10000个数字,FORM窗体可以进行移动。并且未打印完成可以关闭窗体。关闭窗体的同时程序退出运行。
3、使用多线程方法二
(1)把打印的值传给TextBox控件显示
修改Form1.cs的代码:
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; //添加线程命名空间(首先选择快捷键:alt+shift+F10)namespace 多线程{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //创建一个线程去执行这个方法 Thread th = new Thread(Test); //用线程调用Test()方法 th.Start();//标记这个线程准备就绪了,可以随时被执行。具体什么时候执行这个线程由CPU决定。 th.IsBackground = true; //将线程设置为后台线程 } private void Test() { for (int i = 0; i < 10000;i++ ) { textBox1.Text = i.ToString(); //把打印的值传给TextBox控件显示 } } }}
运行结果:
运行会抛出异常。
主线程创建了窗体,新创建的线程调用Test()方法,方法中用到了textBox控件,即新建线程要调用主线程的资源报错。
(2)为FORM添加Load事件,并修改Form1.cs的代码:
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; //添加线程命名空间(首先选择快捷键:alt+shift+F10)namespace 多线程{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //创建一个线程去执行这个方法 Thread th = new Thread(Test); //用线程调用Test()方法 th.Start();//标记这个线程准备就绪了,可以随时被执行。具体什么时候执行这个线程由CPU决定。 th.IsBackground = true;//将线程设置为后台线程 } private void Test() { for (int i = 0; i < 10000;i++ ) { textBox1.Text = i.ToString(); //把打印的值传给TextBox控件显示 } } private void Form1_Load(object sender, EventArgs e) { //取消跨线程的访问---- Control.CheckForIllegalCrossThreadCalls = false; //不捕获对错误线程的调用 } }}
运行结果:
但是在关闭程序时,偶尔也会抛出异常。
主要原因:关闭程序时,新线程没有马上关闭,新建线程仍然在访问文本框控件;但是主线程已经关闭,文本框已经被释放掉不存在了,所以抛出异常。
解决方法:
为窗体关闭添加“FormClosing”事件,并修改Form1.cs的代码:
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; //添加线程命名空间(首先选择快捷键:alt+shift+F10)namespace 多线程{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } Thread th;//为了Form1_FormClosing()访问到th private void button1_Click(object sender, EventArgs e) { //创建一个线程去执行这个方法 th = new Thread(Test); //用线程调用Test()方法 th.Start();//标记这个线程准备就绪了,可以随时被执行。具体什么时候执行这个线程由CPU决定。 th.IsBackground = true;//将线程设置为后台线程 } private void Test() { for (int i = 0; i < 10000;i++ ) { textBox1.Text = i.ToString(); //把打印的值传给TextBox控件显示 } } private void Form1_Load(object sender, EventArgs e) { //取消跨线程的访问---- Control.CheckForIllegalCrossThreadCalls = false; //不捕获对错误线程的调用 } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //当点击关闭窗体的时候,先判断新线程是否为null(新线程已经关闭) if (th!=null) { th.Abort(); //结束这个线程 } } }}
关闭可以正常;关闭后新建线程没法再被重新启动,即线程被Abort()后不能被重新Start()。
4、线程静态方法使用
Thread.Sleep(1)静态方法,可以使当前线程停止一段时间运行。
(1)新建一个C#控制台程序,其代码为:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; //线程命名空间
namespace 多线程静态方法
{
class Program
{
static void Main(string[] args)
{
//线程静态方法
Thread.Sleep(3000); //延时3000毫秒即3秒
Console.WriteLine("hello world");
Console.ReadLine();
}
}
}
运行结果:
延时3秒后,控制台才打印出hello world.
- C 多线程
- C 多线程
- C++:多线程
- c# 多线程
- C#---多线程
- 【C#】多线程
- [C#] 白话C#:多线程
- 【C/C++】多线程
- C/C++windows多线程
- c语言多线程编程
- linux c 多线程
- C#.net使用多线程
- C++builder 中的多线程
- 用C实现多线程
- 用C实现多线程
- C语言多线程创建
- C#Socket多线程实例
- C#:多线程编程探索
- uboot常用部分的文件夹的大致结构(对应的是三星S5PV210的uboot)
- JavaScript 自定义文本框光标——初级版
- 在ccs7下进行DM6467的开发(6):编译驱动模块
- 目的地址和ARP地址应答中的源地址
- 开发工具之IntelliJ IDEA
- C#---多线程
- 【UML】什么是UML
- bzoj1625
- MySql的基本知识储备之数据类型
- AFNetworking访问https出现"NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813"
- SOJ 1020
- 技术学习类网站手收集
- Java中String类的构造函数
- day 08 网络电视精灵