.NET线程控制

来源:互联网 发布:历史数据库设计 编辑:程序博客网 时间:2024/05/21 15:07

线程:

操作系统使用进程将正在执行的不同应用程序分开。线程是操作系统分配处理器时间的基本单元,并且该进程中可以有多个线程同时执行代码。每个线程都维护异常处理程序、调度优先级和一组系统用于在调度该线程前保存线程上下文的结构。线程上下文包括使线程在线程的宿主进程地址空间中无缝地继续执行所需要的所有信息,包括线程的CPU寄存器组合和堆栈。

1)创建线程,使用System.Threading下的Thread类:

Thread thread=new Thread(new ThreadStart(FunctionName));

//线程处理函数

Private void FunctionName()

{}

2)线程启动,使用Thread类的Start方法(方法无参数也无返回值):

//FunctionName为线程处理函数

Thread thread=new Thread(news ThreadStart(FunctionName));

//启动线程

thread.Start();

3)线程暂停与重新启动

线程重新启动后,可以调用Thread.Sleep使当前线程立即阻塞一段时间(参数单位为毫秒),调用Thread.Sleep(Timeout.Infinite)将使线程休眠,直到它被另一个进程调用Thread.Interrupt中断或被Thread.Abort中止为止。注意,一个线程不能对另一个线程调用Sleep.

eg:Thread.Sleep(2000);//使当前线程阻塞2秒

可以通过调用Thread.Suspend来暂停一个线程。当线程自己调用Thread.Suspend时,该调用将阻塞,直到该线程被另一个线程继续为止。当一个线程对另一个线程调用Thread.Suspend时,该调用就成为使另一个线程暂停的非阻塞调用(把一个线程阻塞,自己运行)。

eg:Thread thread=new Thread(new ThreadStart(FunctionName));

thread.Start();

...

thread.Suspend();//自调用阻塞

调用Thread.Resume将一个线程跳出挂起状态并使该进程继续执行,而与调用Thread.Suspend的次数无关。

eg:Thread thread=new Thread(new ThreadStart(FunctionName));

...

thread.Suspend();

thread.Suspend();

//调用Thread.Suspend的2次,但只要调用thread.Resume()线程就继续执行

...

thread.Resume();

通过调用Thread.Join将本线程阻塞直至另一线程终止时再执行)。

eg:Thread thread=new Thread(new ThreadStart(FunctionName));

thread.Start();

...

thread.Join(1000);

经典例子:

        static void Main()

        {

            System.Threading.Thread x = new System.Threading.Thread(new System.Threading.ThreadStart(f1));

            x.Start();

            Console.WriteLine("This is Main.{0}", 1);

            x.Join();//停止前执行线程处理函数f1

            Console.WriteLine("This is Main.{0}", 2);

            Console.ReadLine();

        }

        static void f1()

        {

            System.Threading.Thread y = new System.Threading.Thread(new System.Threading.ThreadStart(f2));

            y.Start();

            y.Join();

            Console.WriteLine("This is F1.{0}",1);

        }

 

        static void f2()

        {

            Console.WriteLine("This is F2.{0}", 1);

        }

输出:

This is Main.1

This is F2.1

This is F1.1

This is Main.2

 

如果: 注释//  x.Join();

结果:

This is Main.1

This is Main.2

This is F2.1

This is F1.1

 

4)线程销毁

线程占用大量的系统资源,使用完后必须使用Thread.Abort和Thread.Interrupt方法销毁。

在主线程调用子线程的Thread.Abort后,会在子线程中抛出一个ThreadAbortException异常,可以在子线程中使用try...catch捕获该异常,并进行相应的处理。但,如果在调用Thread.Abort之前,子线程已经结束,则不出现异常。反之,子线程还未结束则出现异常。

线程不一定会立即中止,或者根本不中止。如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止操作,则会发生这种情况。若要在线程中止之前一直等待,可以在调用 Abort 方法后对该线程调用 Join 方法,但是不能保证等待会结束。

如果对尚未启动的线程调用 Abort,则当调用 Start 时该线程将中止,抛出异常提示“线程正在运行或被终止;它无法重新启动。”。如果对被阻止或正在休眠的线程调用 Abort,则该线程被中断然后中止。

如果在已挂起的线程上调用 Abort,则将在调用 Abort 的线程中引发 ThreadStateException,并将 AbortRequested 添加到被中止的线程的 ThreadState 属性中。直到调用 Resume 后,才在挂起的线程中引发 ThreadAbortException。

如果在执行非托管代码时线程忽略 ThreadAbortException,则当线程开始执行托管代码时,系统将再次引发 ThreadAbortException。

如果同时出现两次对 Abort 的调用,则可能一个调用设置状态信息,而另一个调用执行 Abort。但是,应用程序无法区分这一点。

对线程调用了 Abort 后,线程状态包括 AbortRequested。成功调用 Abort 而使线程终止后,线程状态更改为 Stopped。如果有足够的权限,作为 Abort 目标的线程就可以使用 ResetAbort 方法取消中止操作。有关说明如何调用 ResetAbort 方法的示例,请参见 ThreadAbortException 类。

Thread.Interrupt方法用于中断处于Wait、Sleep、Join线程状态的线程。如果线程当前未阻塞,在等待、休眠或连接状态中,则下次开始阻塞时它将被中断。

eg:Thread thread=new Thread(new ThreadStart(FunctionName));

thread.Start();

...

thread.Join(10000);

thread.Interrupt();

原创粉丝点击