[英]what's the proper way to tell a thread that is executing a loop to break out of the loop and do something else?
以下代码的缺点是,在主线程重置waithandle之后,工作线程既不会立即终止也不会执行最终操作。 相反,它将继续执行它正在进行的操作,直到它到达循环的下一次迭代,此时它将无限期地被阻塞。
static void Main()
{
ManualResetEvent m = new ManualResetEvent(true); // or bool b = true
Thread thread = new Thread(new ThreadStart(delegate()
{
while(m.WaitOne()) //or while(b)
{
//do something
}
//perform final operation and exit
}));
thread.Start();
//do something
m.Reset(); //or b = false
//do something else
}
下面的代码有一个缺点,它使用Abort()方法(有人说它应该不惜一切代价避免),但完全正是我正在寻找的:强制工作线程突破循环主线程告诉它这样做,执行最后一个操作,然后退出。
static void Main()
{
Thread thread = new Thread(new ThreadStart(delegate()
{
try
{
while(true)
{
//do something
}
}
catch(ThreadAbortException e)
{
//perform final operation and exit
}
}));
thread.Start();
//do something
thread.Abort();
//do something else
}
既然这两种解决方案都不理想,那么实现我正在寻找的功能的正确方法是什么?
(我更喜欢不涉及.net 4.5任务的解决方案)
如果您不能使用.NET 4.5(正如我在评论中提到的那样),那么您可以使用布尔值来取消循环。 在这里,我修改了你的第二个选项:
static void Main()
{
volatile bool keepGoing = true;
Thread thread = new Thread(new ThreadStart(delegate()
{
while(keepGoing)
{
//do something
}
//logic to perform when the thread is cancelled
}));
thread.Start();
//do something
keepGoing = false;
//do something else
}
将bool值标记为volatile将确保在检查时始终具有正确的值。 这种方法还可以确保您在循环内执行的任何操作都已完成,而不会处于“脏”状态。
http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.80%29.aspx
您可以使用BackgroundWorker
static void Main()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerAsync();
// do something
worker.CancelAsync();
// do something else
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while(!worker.CancellationPending)
{
// do something
}
// perform final action
}
(代码未经测试)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.