C# 使用标志退出BackgroundWorker
假设我有这样的代码:C# 使用标志退出BackgroundWorker,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,假设我有这样的代码: private bool flag = false; public SomeClass() { public void setup() { worker = new BackgroundWorker(); worker.DoWork += worker_DoWork; if(!worker.IsBusy) worker.RunWorkerAsync(); }
private bool flag = false;
public SomeClass()
{
public void setup()
{
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
if(!worker.IsBusy)
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
if(flag == true)
return;
//whatever You want the background thread to do...
SomeClass.SomeStaticMethodWhichHasLoopInside();
}
}
当用户在我的应用程序中单击退出按钮时,我可以在内部设置flag=true
-这是停止由BackgroundWorker
启动的线程的正确方法吗?
我只想在应用程序想要退出时才这样做,这样我就停止了线程。否则它将被自动杀死?不。不要这样做。它不会像预期的那样工作。您的
标志
字段甚至没有声明为易失性
;字段的真实值可能尚未刷新到内存中。其他线程仍将看到标志
为false,因为它缓存自己的值副本,并且您的BackgroundWorker
可能永远不会结束
相反,只需在DoWork
事件处理程序中调用并检查布尔值
private void OnExit(..)
{
worker.CancelAsync();
}
所以你的嫁妆方法会变得
void worker_DoWork(object sender, DoWorkEventArgs e)
{
while(!worker.CancellationPending)
{
//whatever You want the background thread to do...
}
}
如果没有循环,则需要不时检查CancellationPending
属性
void worker_DoWork(object sender, DoWorkEventArgs e)
{
if(worker.CancellationPending)
return;
//Do something..
if(worker.CancellationPending)
return;
//Do some other thing..
if(worker.CancellationPending)
return;
//Do something else..
}
我只想在应用程序想要退出时才这样做,这样我就停止了
线。或者它会自动被杀死
它将被CLR自动终止,因为该线程是后台线程。但是,不要依赖这个事实,因为我们不知道CLR终止线程时您的线程将执行什么。例如,它可能正在编写一个文件,在这种情况下,您将留下损坏的文件
后果可能更糟,因此建议您自己优雅地停止线程
评论中提出的问题:当循环处于某些状态时,如何取消
其他方法
您似乎正在使用.Net4.5。您可以利用CancellationTokenSource
和CancellationToken
。你也可以考虑使用TPL和异步等待功能,这样会让你的生活更容易。
private CancellationTokenSource tokenSource = new CancellationTokenSource();
private void OnExit(..)
{
tokenSource.Cancel();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
//whatever You want the background thread to do...
SomeClass.SomeStaticMethodWhichHasLoopInside(tokenSource.Token);
}
class SomeClass
{
public static void SomeStaticMethodWhichHasLoopInside(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
//Do something
}
}
}
方法中有一个循环,在
worker\u Dowork
方法中调用该循环-但该方法来自另一个类-我如何引用该方法中的worker?使worker
static?你的意思是:?或者,请提供解决方案的完整代码-我对C有点陌生#我更新了使用SomeStaticMethodWhichHasLoopInside
-的线程外观问题-请给出答案我将如何从该方法检查该属性为什么我不能将worker
声明为静态并检查SomeClass.Static\u worker.CancellationPending
来自somestaticmethodwhichloopinside
——看起来更容易???@user300455这不是一个好的做法。我不鼓励使用静电。如果你愿意,你可以这样做。但是我推荐了正确的方法,这在我的答案中是正确的。最佳实践是用hower编写的,我必须提到,如果您将flag
标记为volatile
,您的解决方案可能会起作用。如果没有volatile
关键字(防止缓存变量),优化程序可能会将线程的标志
存储在L2或寄存器中,而主线程的标志
存储在RAM中,因此,如果没有volatile
您的线程可能永远不会得到通知。