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
您的线程可能永远不会得到通知。