WPF/C#正在取消DoWork外部的BackgroundWorker调用

本文关键字:外部 BackgroundWorker 调用 DoWork 取消 WPF | 更新日期: 2023-09-27 18:00:24

我有一个BackgroundWorker DoWork函数,如下

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

FetchUserData是同一解决方案中另一个项目中另一类(其对象为_feed)中的函数。数据获取过程需要相当长的时间,我希望用户能够在必要时取消该过程。如何将用户的取消操作传递到其他地方的函数调用并停止它?

WPF/C#正在取消DoWork外部的BackgroundWorker调用

您可以使用BackgroundWorker.CancelAsync方法。这里有更多的信息和例子:MSDN

为了更准确地解决您的问题,请将worker传递给FetchUserData。它是sender参数。然后在FetchUserData函数中,您可以检查标志BackgroundWorker.CancellationPending是否已设置并完成您的方法。

void FetchUserData(IEnumerable<Users> userNameCollection, BackgroundWorker worker)
{
    // ...
    if(worker.CancellationPending)
    {
        // Finish method..
    }
}

WorkerGetFeedData方法:

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

向工作线程发送一条消息(事件),该消息更改布尔值,指示工作线程应该结束/取消自身

编辑:我读你的问题有点快,遗漏了重要部分。在试图弥补的时候,我发现了这篇有趣的文章,它可能会有所帮助:

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

当用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 ...");
        }
    }
}

这种方法的问题在于,它使用Thread.Artrt(),无论线程在做什么,它都会中断线程。这可能会导致句柄左开、内存泄漏等。因此,尽管这可能会有所帮助,但使用它很可能是非常不明智的。

Ian Griffiths认为,另一种(强制)取消线程的方法是在它自己的独立进程中运行它:http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation您可以在不影响进程内部状态的情况下随时杀死它。