backgroundworker.CancellationPending == true的退出功能

时间:2014-09-25 09:17:39

标签: c# wpf backgroundworker

我目前正试图让我的函数在backgroundworker.CancellationPending == true时自行取消。

我有一个这样的课程:

public class ImportPostManager
{
    public event ProgressChangedEventHandler ProgressChanged;

    protected virtual void OnProgressChanged(int progress)
    {
        if (ProgressChanged != null)
        {
            ProgressChanged(this, new ProgressChangedEventArgs(progress, null));
        }
    }

    public void DoSomeStuff()
    {
        while(something == true)
        {
            if(backgroundworker.CancellationPending) return; //Here's my problem

            //KeepDoingStuff and report progress
        }
    }
}

我从backgroundworker.DoWork()中的表单调用该函数但是如何让该类听取backgroundworker.CancellationPending?我无法在.DoWork()中执行此操作,因为它看起来像这样:

void _progressDialog_DoWork(object sender, DoWorkEventArgs e)
{
    Managers.ImportPostManager.Instance.ProgressChanged += (s, pe) => dialog.ReportProgress(pe.ProgressPercentage, null, pe.ProgressPercentage.ToString() + "%);
    Managers.ImportPostManager.Instance.DoSomeStuff();
}

...而且我不想将背景工作者发送到函数.DoSomeStuff()。有没有办法使用事件或东西来获得我想要的东西?我还没有找到任何可以解释如何以我能理解的方式......

1 个答案:

答案 0 :(得分:0)

如果你在DoSomeStuff出售而没有直接通过工作人员,并假设它是阻止的(看起来是公平的),你最好的选择可能是添加一个Func<bool>函数的参数。

public void DoSomeStuff(Func<bool> ShouldCancel)
{
    while (whatever == whateverElse && !ShouldCancel())
    {
        // Do work
    }
}

然后你可以从你的DoWork处理程序中调用它。

void _progressDialog_DoWork(object sender, DoWorkEventArgs e)
{
    Managers.ImportPostManager.Instance.ProgressChanged += (s, pe) => dialog.ReportProgress(pe.ProgressPercentage, null, pe.ProgressPercentage.ToString() + "%);
    Managers.ImportPostManager.Instance.DoSomeStuff(() => backgroundworker.CancellationPending);
}

每次都会得到评估,生活会很好。

虽然如果您担心这样的情况发生了很多,但是可能值得研究一种更高级的多线程形式,即使只是通过System.Threading.Tasks命名空间提供的形式。在那里,您将有更多选择取消。但是如果你正在寻找快速而简单的东西,那么添加该函数就可以解决问题了,并且它可以在多个上下文中工作,所以如果你选择反对它,那么你的助手类将不会与后台工作者的使用联系在一起。将来

当然,如果您没有使用BackgroundWorker.CancellationPending属性(或者,如果我没记错,Cancel()方法),您可以更改该功能并检查{{ 1}},只需针对该CancellationToken调用(或者更确切地说,针对其Cancel())。这在某些方面并不理想,但是如果你想要转向更多的东西,就像我之前说过的那样,那将会更加清洁。当然,如果你现在已经设置了这个功能,你也可以很容易地在CancellationTokenSource之上层叠令牌,所以根据你的选择,你不能永远地选择一个或另一个时刻。