C#及WPF多线程定义和使用

Windows系统是一个多线程的操作系统,进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。是应用程序的一个运行例程,是应用程序的一次动态执行过程。

多线程的优点

1.多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程

2. 提高了CPU的利用率,就可以直接提高程序的整体执行速度

多线程的缺点:

1.线程开的越多,内存占用越大

2.协调和管理代码的难度加大,需要CPU时间跟踪线程

3.线程之间对资源的共享可能会产生可不遇知的问题

多线程定义:

不带参数线程:

private void Main()
{
    Thread t1 = new Thread(new ThreadStart(ThreadMethod)); 
    t1.IsBackground = true;//默认后台线程
    t1.Start();
}


private void ThreadMethod()
{
//Thread method 
}

带参数线程:ParameterizedThreadStart委托的参数类型必须是Object.

private void Main()
{
    Thread t1 = new Thread(new ParameterizedThreadStart(ThreadMethod)); 
    t1.IsBackground = true;
    t1.Start("thread param");
}


private void ThreadMethod(object param)
{
    //Thread method 
    Console.WriteLine(param.toString());
}

使用匿名委托或Lamba表达式为Thread构造方法赋值:

//通过匿名委托创建
Thread thread1 = new Thread(delegate() { Console.WriteLine("我是通过匿名委托创建的线程"); });
thread1.Start();
//通过Lambda表达式创建
Thread thread2 = new Thread(() => Console.WriteLine("我是通过Lambda表达式创建的委托"));
thread2.Start();

IsBackground :只有所有的前台线程都结束,应用程序才能结束,默认情况下创建的线程都是前台线程.只要所有的前台线程结束,后台线程自动结束。通过Thread.IsBackground设置后台线程。必须在调用Start方法之前设置线程的类型,否则一旦线程运行,将无法改变其类型.

Join:阻塞调用线程,直到该线程终止.

Abort:抛出 ThreadAbortException 异常让线程终止,终止后的线程不可唤醒

挂起(Suspend)和唤醒(Resume):已淘汰,由于线程的执行顺序和程序的执行情况不可预知,所以使用挂起和唤醒容易发生死锁的情况,在实际应用中应该尽量少用.

Sleep:把正在运行的线程挂起一段时间

Priority线程优先级:AboveNormal BelowNormal Highest Lowest Normal,默认为Normal.

线程池(ThreadPool):由于线程的创建和销毁需要耗费一定的开销,过多的使用线程会造成内存资源的浪费,出于对性能的考虑,于是引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,然后委派给线程池的一个线程执行,线程执行完不会被立即销毁,这样既可以在后台执行任务,又可以减少线程创建和销毁所带来的开销. (使用情景:1.单个任务处理的时间比较短  2.需要处理的任务的数量大)

//设置线程池线程最大数,减少创建占用资源内存
ThreadPool.SetMaxThreads (int workerThreads,int completionPortThreads);
//不带参数线程
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名));
//带参数线程
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名), 参数);

线程同步:是指在某一时刻只有一个线程可以访问变量,使用lock关键字.

Lock(expression)
{
   //statement_block
}
/*
expression代表你希望跟踪的对象:
如果你想保护一个类的实例,一般地,你可以使用this;
如果你想保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了
 lock(this)尽量不要使用,this指的是整个外层方法,当锁住后导致别的进程也无法访问该方法,应lock一个不影响其他操作的私有对象
*/

异步回调:如果想异步方法完成后执行某一操作,可以使用异步回调.

Action<string> action = this.DoSomethingLong;
// 定义一个回调
AsyncCallback callback = p =>
{
       Console.WriteLine($"异步完成后执行");
};
// 回调作为参数
action.BeginInvoke("btnAsyncAdvanced_Click", callback, null);

上一篇:WPF 入门教程DockPanel介绍


下一篇:WPF中GroupBox只能包含一个元素的问题(Error XLS0501 The property ‘Content‘ is set more than once)