简体   繁体   English

WPF / C#取消DoWork之外的BackgroundWorker调用

[英]WPF/C# Cancelling BackgroundWorker call outside DoWork

I have a BackgroundWorker DoWork function as follows 我有一个BackgroundWorker DoWork函数,如下所示

    private void WorkerGetFeedData(object sender, DoWorkEventArgs args)
    {
            _feed.FetchUserData(_userNameCollection);
    }

The FetchUserData is a function in another class(whose object is _feed ) in another project in the same solution. FetchUserData是同一解决方案中另一个项目中另一个类(其对象是_feed )中的一个函数。 The data fetch process takes considerable time and I'd like for the user to be able to cancel the process if necessary. 数据提取过程需要花费大量时间,我希望用户能够在必要时取消该过程。 How do I convey a cancel operation from the user to a function call elsewhere and just stop it? 如何将取消操作从用户传递到其他地方的函数调用,然后将其停止?

You can use BackgroundWorker.CancelAsync method. 您可以使用BackgroundWorker.CancelAsync方法。 Here's more info with example: MSDN 这里是示例的更多信息: MSDN

To be more exact to your problem, pass the worker to FetchUserData . 为了更精确地解决您的问题,请将工作FetchUserData传递给FetchUserData It is the sender parameter. 它是发送者参数。 Then in the FetchUserData function you can check if the flag BackgroundWorker.CancellationPending is set and finish your method. 然后,在FetchUserData函数中,可以检查标志BackgroundWorker.CancellationPending是否已设置并完成您的方法。

void FetchUserData(IEnumerable<Users> userNameCollection, BackgroundWorker worker)
{
    // ...

    if(worker.CancellationPending)
    {
        // Finish method..
    }
}

And the WorkerGetFeedData method: 和WorkerGetFeedData方法:

private void WorkerGetFeedData(object sender, DoWorkEventArgs args)
{
        var worker = sender as BackgroundWorker;
        if(worker != null)
            _feed.FetchUserData(_userNameCollection, worker);
}

Send a message (event) to the worker thread that changes a boolean, indicating that the worker thread should end/cancel itself. 向工作线程发送一条消息(事件),该消息会更改一个布尔值,指示工作线程应自行结束/取消。

Edit : I was a bit quick reading your question, missing the important part. 编辑 :我有点快速阅读您的问题,但缺少重要部分。 While trying to make up I found this interesting article which might help: 在尝试化妆时,我发现了这篇有趣的文章,可能会有所帮助:

http://ondotnet.com/pub/a/dotnet/2003/02/18/threadabort.html http://ondotnet.com/pub/a/dotnet/2003/02/18/threadabort.html

It does work when simulating a long running process with Thread.Sleep(), being at work I dont have time right now to write code to test it on a proper application/long running task. 当使用Thread.Sleep()模拟长时间运行的进程时,它确实可以工作,但现在我还没有时间编写代码来在适当的应用程序/长时间运行的任务上对其进行测试。

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(new ThreadStart(Foo));
        thread.Start();
        Console.ReadKey();
        thread.Abort(); // cause ThreadAbortException to be thrown    
        Console.ReadKey();
    }

    static void Foo()
    {
        try
        {
            while( true )
            {
                Console.WriteLine("Long running process...");
                Thread.Sleep(100000);
            }
        }
        catch( ThreadAbortException ex )
        {
            Console.WriteLine(ex.Message);
        }
        finally 
        {
            Console.WriteLine("Thread Closing ...");
        }
    }
}

The problem with this approach is - it uses Thread.Abort() - which interrupts the thread no matter what it is doing. 这种方法的问题是-它使用Thread.Abort()-无论执行什么操作都会中断线程。 This can lead to left open handles, memory leaks, etc. So while it may help it would most likely be very unwise to use. 这可能会导致手柄拉开,内存泄漏等。因此,尽管有帮助,但使用起来非常不明智。

Ian Griffiths supposes that another way to (force) cancel a thread would be to run it in its own, seperate process: http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation which you can kill whenever without affecting your process's internal state. 伊恩·格里菲斯(Ian Griffiths)认为(强制)取消线程的另一种方法是在其单独的进程中运行它: http : //www.interact-sw.co.uk/iangblog/2004/11/12/cancellation可以在不影响进程内部状态的情况下杀死它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM