每一个操作系统上运行的应用程序都是一个进程,一个进程(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方法
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/107132.html