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;
namespace WindowsFormsApplication1 {
public partial class Form1: Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
//http://blog.csdn.net/lonet/article/details/7048616
//Thread.Suspend():挂起线程,或者如果线程已挂起,则不起作用;
//Thread.Resume():继续已挂起的线程
//Thread.Interrupt():中止处于 Wait或者Sleep或者Join 线程状态的线程
//Thread.Join():阻塞调用线程,
//Thread.Sleep():将当前线程阻塞指定的毫秒数
//Thread.Abort():以开始终止此线程的过程。如果线程已经在终止,则不能通过Thread.Start()来启动线程。
//Thread.IsAlive属性:获取一个值,该值指示当前线程的执行状态。如果此线程已启动并且尚未正常终止或中止,则为 true;否则为 false
//Thread.Name 属性:获取或设置线程的名称
//Thread.Priority 属性:获取或设置一个值,该值指示线程的调度优先级。
//Thread.ThreadState 属性:获取一个值,该值包含当前线程的状态。
//在给定的时间和指定的代码段只能被一个线程访问,Monitor 类非常适合于这种情况的线程同步
//将代码放入try…finally内,在finally调用Monitor.Exit,这样的话最后一定会释放锁。第二种方法是:利用C#的lock()方法lock(this);
//C# lock申明提供了与Monitoy.Enter和Monitoy.Exit同样的功能,这种方法用在你的代码段不能被其他独立的线程中断的情况
//Monitor.Enter 方法:在指定对象上获取排他锁
//Monitor.TryEnter 方法:试图获取指定对象的排他锁
//Monitor.Exit 方法:释放指定对象上的排他锁。
//Monitor.Wait 方法:释放对象上的锁并阻塞当前线程,直到它重新获取该锁。
//Monitor.Pulse 方法:通知等待队列中的线程锁定对象状态的更改。
//Monitor.PulseAll 方法:通知所有的等待线程对象状态的更改。
// WaitHandle类作为基类来使用的,它允许多个等待操作。这个类封装了win32的同步处理方法。WaitHandle对象通知其他的线程它需要对资源排他性的访问,其他的线程必须等待,直到WaitHandle不再使用资源和等待句柄没有被使用
//Mutex 类:同步基元也可用于进程间同步
//AutoResetEvent:通知一个或多个正在等待的线程已发生事件。无法继承此类。
//ManualResetEvent:当通知一个或多个正在等待的线程事件已发生时出现。无法继承此类。
// 这些类定义了一些信号机制使得对资源排他性访问的占有和释放。他们有两种状态:signaled 和 nonsignaled。Signaled状态的等待句柄不属于任何线程,除非是nonsignaled状态。拥有等待句柄的线程不再使用等待句柄时用set方法,其他的线程可以调用Reset方法来改变状态或者任意一个WaitHandle方法要求拥有等待句柄,这些方法见下面
//WaitAll:等待指定数组中的所有元素收到信号
//WaitAny:等待指定数组中的任一元素收到信号
//WaitOne:当在派生类中重写时,阻塞当前线程,直到当前的 WaitHandle 收到信号
//这些wait方法阻塞线程直到一个或者更多的同步对象收到信号WaitHandle对象封装等待对共享资源的独占访问权的操作系统特定的对象无论是收管代码还是非受管代码都可以使用。但是它没有Monitor使用轻便,Monitor是完全的受管代码而且对操作系统资源的使用非常有效率
//Mutex是另外一种完成线程间和跨进程同步的方法,它同时也提供进程间的同步。它允许一个线程独占共享资源的同时阻止其他线程和进程的访问
//Timer类对于周期性的在分离的线程执行任务是非常有效的,TimerCallback代表负责指定与Timer对象相关联的方法(就是要周期执行的任务)和状态。它在方法应得的时间过去之后调用一次并且周期性的调用这个方法直到调用了Dispose方法释放了Timer的所有资源。系统自动分配分离的线程。
//TimerCallback tcallback = new TimerCallback(方法);
//Timer atimer = new Timer(tcallback, null, 20, 150);
//atimer.Change(100, 300);
//atimer.Dispose();
//无参
Thread t = new Thread(new ThreadStart(shmsg1));
t.Start();
//传参数
string msg = "带参数";
Thread tt = new Thread(new ParameterizedThreadStart(shmsg2));
tt.Start(msg);
//线程池 无参 ThreadPool类时线程池将被创建。它有一个默认的上限,即每处理器最多可以有25个,调用ThreadPool.RegisterWaitForSingleObject方法来传递一个System.Threading.WaitHandle,当被通知或者时间超过了调用被System.Threading.WaitOrTimerCallback包装的方法
ThreadPool.QueueUserWorkItem(new WaitCallback(shmsg4));
ThreadPool.QueueUserWorkItem(new WaitCallback(shmsg5), "线程池 有参");
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o) {
MessageBox.Show("线程池的匿名方法");
}));
//.使用自定义委托 6 有参
WaitCallback wc = new WaitCallback(weiw);
ThreadPool.QueueUserWorkItem(wc, "自定义委托调用线程池");
//定义委托很麻烦用这个:7 使用system.Action
WaitCallback wcc = new WaitCallback(weiww);
ThreadPool.QueueUserWorkItem(wcc, "使用system.Action");
//使用System.Func 8 Invoke调用主窗体操作之后,还希望在调用完得到一个返回值
WaitCallback w = new WaitCallback(shmsg5);
ThreadPool.QueueUserWorkItem(w, "使用system.Func");
}
//.Invoke方法签名:
//object Control.Invoke(Delegate Method);
//object Control.Invoke(Delegate Method, params object[] args);
//在业务线程里面执行完毕,要改变窗体控件的值了,此时,如果直接通过this得到控件的句柄,然后对它进行操作是会抛异常的,.Net WinForm Application里面是不允许这样的操作的。这是,可以调用Invoke方法--下面这样我会每个都定义一个委托 有点麻烦 6
private delegate void wei(string msg);
public void weiw(object o) {
this.Invoke(new wei(shmsg6), o.ToString());
}
//Action有很多个重载,可以无参数(非泛型),而最多可以有四个参数,同样采用匿名方法,不使用泛型形式的System.Action 7
public void weiww(object o) {
this.Invoke(new Action < string > (shmsg6), o.ToString());
this.Invoke(new Action(delegate() {
MessageBox.Show("第二种方式 ");
}));
}
// 带有返回值的: 8
private void w(object o) {
System.Func < string,
int > f = new Func < string,
int > (wi);
object result = this.Invoke(f, o.ToString());
MessageBox.Show(result.ToString());
}
private int wi(string o) {
if (o == "使用system.Func") {
return 1;
}
return 0;
}
//下面是各种方法
private void shmsg1() {
//加锁,让线程排队执行
lock(this) {
MessageBox.Show("第一种 无参");
}
}
private void shmsg2(object msg) {
lock(this) {
MessageBox.Show(msg.ToString());
}
}
private void shmsg3() {
//加锁,让线程排队执行
lock(this) {
MessageBox.Show("thread start ");
}
}
private void shmsg4(object o) {
//加锁,让线程排队执行
lock(this) {
MessageBox.Show("thread start ");
}
}
private void shmsg5(object o) {
//加锁,让线程排队执行
lock(this) {
MessageBox.Show(o.ToString());
}
}
private void shmsg6(string o) {
//加锁,让线程排队执行
lock(this) {
MessageBox.Show(o.ToString());
}
}
}
}