该示例创建一个名为 Worker 的类,该类包含辅助线程将执行的方法 DoWork。这实际上是辅助线程的 Main 函数。辅助线程将通过调用此方法来开始执行,并在此方法返回时自动终止。DoWork 方法如下所示:
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("worker thread: working...");
}
Console.WriteLine("worker thread: terminating gracefully.");
}
Worker 类包含另一个方法,该方法用于通知 DoWork 它应当返回。此方法名为 RequestStop,如下所示:
public void RequestStop()
{
_shouldStop = true;
}
RequestStop 方法只是将 true 赋给 _shouldStop 数据成员。由于此数据成员由 DoWork 方法来检查,因此这会间接导致 DoWork 返回,从而终止辅助线程。但是,需要注意:DoWork 和 RequestStop 将由不同线程执行。DoWork 由辅助线程执行,而 RequestStop 由主线程执行,因此 _shouldStop 数据成员声明为 volatile,如下所示:
private volatile bool _shouldStop;
volatile 关键字用于通知编译器,将有多个线程访问 _shouldStop 数据成员,因此它不应当对此成员的状态做任何优化假设
通过将 volatile 与 _shouldStop 数据成员一起使用,可以从多个线程安全地访问此成员,而不需要使用正式的线程同步技术,但这仅仅是因为 _shouldStop 是 bool。这意味着只需要执行单个原子操作就能修改 _shouldStop。但是,如果此数据成员是类、结构或数组,那么,从多个线程访问它可能会导致间歇的数据损坏。假设有一个更改数组中的值的线程。Windows 定期中断线程,以便允许其他线程执行,因此线程会在分配某些数组元素之后和分配其他元素之前被中断。这意味着,数组现在有了一个程序员从不想要的状态,因此,读取此数组的另一个线程可能会失败。
在实际创建辅助线程之前,Main 函数会创建一个 Worker 对象和 Thread 的一个实例。线程对象被配置为:通过将对 Worker.DoWork 方法的引用传递给 Thread 构造函数,来将该方法用作入口点,如下所示:
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
此时,尽管辅助线程对象已存在并已配置,但尚未创建实际的辅助线程。只有当 Main 调用 Start 方法后,才会创建实际的辅助线程:
workerThread.Start();
此时,系统将启动辅助线程的执行,但这是在与主线程异步执行的。这意味着 Main 函数将在辅助线程进行初始化的同时继续执行代码。为了保证 Main 函数不会尝试在辅助线程有机会执行之前将它终止,Main 函数将一直循环,直到辅助线程对象的 IsAlive 属性设置为 true:
while (!workerThread.IsAlive);
下一步,通过调用 Sleep 来将主线程中断片刻。这保证了辅助线程的 DoWork 函数在 Main 函数执行其他任何命令之前,在 DoWork 方法内部执行若干次循环:
Thread.Sleep(1);
在 1 毫秒之后,Main 将通知辅助线程对象,它应当使用 Worker.RequestStop 方法(前面已介绍)自行终止:
workerObject.RequestStop();
还可以通过调用 Abort 来从一个线程终止另一个线程,但这会强行终止受影响的线程,而不管它是否已完成自己的任务,并且不提供清理资源的机会。此示例中显示的技术是首选方法。
最后,Main 函数对辅助线程对象调用 Join 方法。此方法导致当前线程阻塞或等待,直到对象所表示的线程终止。因此,直到辅助线程返回后,Join 才会返回,然后自行终止:
workerThread.Join();
此时,只有执行 Main 的主线程还存在。它会显示一条最终消息,然后返回,从而使主线程也终止。
下面显示了完整的示例:
using System;
using System.Threading;
public class Worker
{
// This method will be called when the thread is started.
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("worker thread: working...");
}
Console.WriteLine("worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Volatile is used as hint to the compiler that this data
// member will be accessed by multiple threads.
private volatile bool _shouldStop;
}
public class WorkerThreadExample
{
static void Main()
{
// Create the thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
// Start the worker thread.
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread...");
// Loop until worker thread activates.
while (!workerThread.IsAlive);
// Put the main thread to sleep for 1 millisecond to
// allow the worker thread to do some work:
Thread.Sleep(1);
// Request that the worker thread stop itself:
workerObject.RequestStop();
// Use the Join method to block the current thread
// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("main thread: Worker thread has terminated.");
}
}
C# 怎么删除线程
1.thread.Abort();2.如下实例,用变量来控制进程的退出 public void MyThread(){ \/\/MyThreadStat:线程状态,ThreadStatus.Running是我自己定义的 \/\/当启动线程时,给MyThreadStat付初值 \/\/如果要退出线程,只要设置MyThreadStat的值级可以了。\/\/这样比Thread.Abort()方法更好用。while (MyThreadStat ...
如何有效地kill在C#中的线程
没错,标准C++ IO流也会很好的在exit退出时得到flush并且释放资源,这些东西并不会造成资源的浪费(系统调用main函数入口类似于exit(main(argc,argv))).表面上似乎所有的问题都能随着进程的结束来得到很好的处理,其实并不然,我们程序从堆上分配的内存就不能得到很好的释放,如new ,delete后的存储空间...
C#如何停止后台线程
Thread t = new Thread(new ThreadStart(run)); \/\/运行run方法的线程 t.Abort(); \/\/摧毁它
c#如何结束处于监听状态的线程
4、如果该线程位于某进程, 且该进程仅有这一个线程, 可直接结束进程以结束此线程。
c#关闭窗口怎么强制退出所有运行的线程
将线程的isbauckground设置为true 当住线程关闭时(也就是推出程序时),其他线程将自动关闭
C#中如何彻底摧毁线程
闪退是因为你创建的子线程出现错误了。编译器不会给你的子线程报错,而是直接退出。要么别加线程,要加就要解决里面的错误,方法是:在线程里设置try catch。就不会闪退了。你还是要解决这个问题才对!设置断点跟进。
C#如何释放线程
1、首先我们在Visual Studio中创建一个winform程序。2、然后在winform的主界面中我们拖入一个按钮,如下图所示,接下来会点击这个按钮后创建线程。3、接下来我们定义创建线程需要执行的方法,如下图所示,这里只是简单的做了个循环。4、紧接着就需要定义按钮的点击事件,在点击事件中我们通过ThreadStart来...
在C#中如何关闭线程
线程没有实例化这个概念,只有启动,停止,暂停等方法, 每个线程都会有一个名字,调用每个线程的 Abort() 方法就可以停止该线程了。补充:你的变量名是在哪里声明的? 如果要在另一个按钮事件中也能访问,必须声明为类的变量。
C#中关闭程序时如何自动结束正在运行的线程?
\/\/窗体关闭事件中添加如下代码 if(this.thread != null || this.thread.IsAlive){ this.thread.Abort();this.thread = null;} \/\/就OK了
C# 怎样快速中断一个阻塞的线程?
关闭线程一般有2个办法.异步关闭和延迟关闭..异步关闭就是你在需要关闭已经阻塞的进程线程了的时候..创建一个新的线程来关闭它.延迟关闭的话就是你在有可能遇到问题的线程里面不断判断自身是否符合要呗关闭的条件..如果是你说取消传输文件这样的线程的话..应该是不允许有延迟的..那你就用异步关闭去...