.Net中后台线程和前台线程的区别
2012-12-10 12:59
288 查看
.Net中的线程,可以分为后台线程和前台线程。后台线程与前台线程并没有本质的区别,它们之间唯一的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。其实,说白了就是当前台线程都结束了的时候,整个程序也就结束了,即使还有后台线程正在运行,此时,所有剩余的后台线程都会被停止且不会完成.但是,只要还有一个前台线程没有结束,那么它将阻止程序结束.这就是为什么有些设计不够完美的WinForm程序,在某种特定的情况下,即使所有的窗口都关闭了,但是在任务管理器的管理列表里仍然可以找到该程序的进程,仍然在消耗着CPU和内存资源.因此,在WinForm程序中,关闭所有窗口前,应该停止所有前台线程,千万不要遗忘了某个前台线程.应用程序进程的存亡由前台线程决定而于后台线程无关.这就是它们的区别.线程默认为前台线程。
此外,改变线程从前台到后台不会以任何方式改变它在CPU协调程序中的优先级和状态。因为前台后线程与程序进程的优先级无关.
下面的代码示例对比了前台线程与后台线程的行为。创建一个前台线程和一个后台线程。前台线程使进程保持运行,直到它完成它的 while 循环。前台线程完成后,进程在后台线程完成它的 while 循环之前终止。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TestBackgroundThread
{
class Program
{
static void Main()
{
BackgroundTest shortTest = new BackgroundTest(10);
Thread foregroundThread =
new Thread(new ThreadStart(shortTest.RunLoop));
foregroundThread.Name = "前台线程";
BackgroundTest longTest = new BackgroundTest(50);
Thread backgroundThread =
new Thread(new ThreadStart(longTest.RunLoop));
backgroundThread.Name = "后台线程";
backgroundThread.IsBackground = true;
foregroundThread.Start();
backgroundThread.Start();
//Console.ReadLine(); //不需要此行
}
}
class BackgroundTest
{
int maxIterations;
public BackgroundTest(int maxIterations)
{
this.maxIterations = maxIterations;
}
public void RunLoop()
{
String threadName = Thread.CurrentThread.Name;
for (int i = 0; i < maxIterations; i++)
{
Console.WriteLine("{0} count: {1}",
threadName, i.ToString());
Thread.Sleep(500);
}
Console.WriteLine("{0} finished counting.", threadName);
}
}
}
Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
一个线程是前台线程还是后台线程可由它的IsBackground属性来决定。这个属性是可读又可写的。它的默认值为false,即意味着一个线程默认为前台线程。我们可以将它的IsBackground属性设置为true,从而使之成为一个后台线程。
下面的例子是一个控制台程序,程序一开始便启动了10个线程,每个线程运行5秒钟时间。由于线程的IsBackground属性默认为false,即它们都是前台线程,所以尽管程序的主线程很快就运行结束了,但程序要到所有已启动的线程都运行完毕才会结束。示例代码如下:
using System;
using System.Threading;
class MyApp
{
public static void Main()
{
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(new ThreadStart(ThreadFunc));
thread.Start();
}
}
private static void ThreadFunc()
{
DateTime start = DateTime.Now;
while ((DateTime.Now - start).Seconds < 5)
;
}
}
接下来我们对上面的代码进行略微修改,将每个线程的IsBackground属性都设置为true,则每个线程都是后台线程了。那么只要程序的主线程结束了,整个程序也就结束了。示例代码如下:
using System;
using System.Threading;
class MyApp
{
public static void Main()
{
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(new ThreadStart(ThreadFunc));
thread.IsBackground = true;
thread.Start();
}
}
private static void ThreadFunc()
{
DateTime start = DateTime.Now;
while ((DateTime.Now - start).Seconds < 5)
;
}
}
既然前台线程和后台线程有这种差别,那么我们怎么知道该如何设置一个线程的IsBackground属性呢?下面是一些基本的原则:对于一些在后台运行的线程,当程序结束时这些线程没有必要继续运行了,那么这些线程就应该设置为后台线程。比如一个程序启动了一个进行大量运算的线程,可是只要程序一旦结束,那个线程就失去了继续存在的意义,那么那个线程就该是作为后台线程的。而对于一些服务于用户界面的线程往往是要设置为前台线程的,因为即使程序的主线程结束了,其他的用户界面的线程很可能要继续存在来显示相关的信息,所以不能立即终止它们。这里我只是给出了一些原则,具体到实际的运用往往需要编程者的进一步仔细斟酌。
此外,改变线程从前台到后台不会以任何方式改变它在CPU协调程序中的优先级和状态。因为前台后线程与程序进程的优先级无关.
下面的代码示例对比了前台线程与后台线程的行为。创建一个前台线程和一个后台线程。前台线程使进程保持运行,直到它完成它的 while 循环。前台线程完成后,进程在后台线程完成它的 while 循环之前终止。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TestBackgroundThread
{
class Program
{
static void Main()
{
BackgroundTest shortTest = new BackgroundTest(10);
Thread foregroundThread =
new Thread(new ThreadStart(shortTest.RunLoop));
foregroundThread.Name = "前台线程";
BackgroundTest longTest = new BackgroundTest(50);
Thread backgroundThread =
new Thread(new ThreadStart(longTest.RunLoop));
backgroundThread.Name = "后台线程";
backgroundThread.IsBackground = true;
foregroundThread.Start();
backgroundThread.Start();
//Console.ReadLine(); //不需要此行
}
}
class BackgroundTest
{
int maxIterations;
public BackgroundTest(int maxIterations)
{
this.maxIterations = maxIterations;
}
public void RunLoop()
{
String threadName = Thread.CurrentThread.Name;
for (int i = 0; i < maxIterations; i++)
{
Console.WriteLine("{0} count: {1}",
threadName, i.ToString());
Thread.Sleep(500);
}
Console.WriteLine("{0} finished counting.", threadName);
}
}
}
Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
一个线程是前台线程还是后台线程可由它的IsBackground属性来决定。这个属性是可读又可写的。它的默认值为false,即意味着一个线程默认为前台线程。我们可以将它的IsBackground属性设置为true,从而使之成为一个后台线程。
下面的例子是一个控制台程序,程序一开始便启动了10个线程,每个线程运行5秒钟时间。由于线程的IsBackground属性默认为false,即它们都是前台线程,所以尽管程序的主线程很快就运行结束了,但程序要到所有已启动的线程都运行完毕才会结束。示例代码如下:
using System;
using System.Threading;
class MyApp
{
public static void Main()
{
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(new ThreadStart(ThreadFunc));
thread.Start();
}
}
private static void ThreadFunc()
{
DateTime start = DateTime.Now;
while ((DateTime.Now - start).Seconds < 5)
;
}
}
接下来我们对上面的代码进行略微修改,将每个线程的IsBackground属性都设置为true,则每个线程都是后台线程了。那么只要程序的主线程结束了,整个程序也就结束了。示例代码如下:
using System;
using System.Threading;
class MyApp
{
public static void Main()
{
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(new ThreadStart(ThreadFunc));
thread.IsBackground = true;
thread.Start();
}
}
private static void ThreadFunc()
{
DateTime start = DateTime.Now;
while ((DateTime.Now - start).Seconds < 5)
;
}
}
既然前台线程和后台线程有这种差别,那么我们怎么知道该如何设置一个线程的IsBackground属性呢?下面是一些基本的原则:对于一些在后台运行的线程,当程序结束时这些线程没有必要继续运行了,那么这些线程就应该设置为后台线程。比如一个程序启动了一个进行大量运算的线程,可是只要程序一旦结束,那个线程就失去了继续存在的意义,那么那个线程就该是作为后台线程的。而对于一些服务于用户界面的线程往往是要设置为前台线程的,因为即使程序的主线程结束了,其他的用户界面的线程很可能要继续存在来显示相关的信息,所以不能立即终止它们。这里我只是给出了一些原则,具体到实际的运用往往需要编程者的进一步仔细斟酌。
相关文章推荐
- 前台线程和后台线程的区别
- c#前台线程与后台线程的区别和联系
- C#.Net前台线程与后台线程的区别
- 前台线程与后台线程的区别
- C#.Net前台线程与后台线程的区别
- HttpUtility.UrlDecode(),HttpUtility()escape()、encodeURI()、encodeURIComponent()区别详解以及相应的前台解码和.net后台解码
- C#前台线程与后台线程的区别和联系 (转)
- HttpUtility.UrlDecode(),HttpUtility()escape()、encodeURI()、encodeURIComponent()区别详解以及相应的前台解码和.net后台解码
- 前台线程与后台线程的区别
- C#中前台线程和后台线程的区别与联系
- .Net后台使用RegisterClientScriptBlock和RegisterStartupScript调用前台的JS 区别
- 前台线程和后台线程的区别
- c#前台线程与后台线程的区别和联系
- c#前台线程与后台线程的区别和联系
- 后台线程与前台线程在运行性能上有什么区别
- HttpUtility.UrlDecode(),HttpUtility()escape()、encodeURI()、encodeURIComponent()区别详解以及相应的前台解码和.net后台解码
- C#中前台线程和后台线程的区别
- C# 前台线程与后台线程的区别和联系
- 前台线程和后台线程的区别
- c#前台线程与后台线程的区别和联系