WPF / C # Отмена вызова BackgroundWorker вне DoWork - PullRequest
2 голосов
/ 23 июня 2011

У меня есть BackgroundWorker DoWork функция следующим образом

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

FetchUserData - это функция в другом классе (чей объект _feed) в другом проекте того же решения.Процесс извлечения данных занимает значительное время, и я бы хотел, чтобы пользователь мог отменить процесс в случае необходимости.Как передать операцию отмены от пользователя на вызов функции в другом месте и просто остановить его?

Ответы [ 2 ]

4 голосов
/ 23 июня 2011

Вы можете использовать BackgroundWorker.CancelAsync метод. Вот больше информации с примером: MSDN

Чтобы быть более точным в вашей проблеме, передайте работника на FetchUserData. Это параметр отправителя. Затем в функции 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);
}
0 голосов
/ 23 июня 2011

Отправить сообщение (событие) в рабочий поток, который изменяет логическое значение, указывая, что рабочий поток должен завершить / отменить сам.

Редактировать : IЯ немного быстро прочитал ваш вопрос, упустив важную часть.Пытаясь сделать макияж, я нашел эту интересную статью, которая может помочь:

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.Abort (), который прерывает поток независимо от того, чтоэто делает.Это может привести к тому, что останутся открытые дескрипторы, утечки памяти и т. Д. Поэтому, хотя это может помочь, скорее всего, было бы очень неразумно использовать.

Ян Гриффитс полагает, что другой способ (принудительно) отменить поток - этозапустите его в отдельном отдельном процессе: http://www.interact -sw.co.uk / iangblog / 2004/11/12 / cancellation , который вы можете уничтожить в любое время, не затрагивая внутреннее состояние вашего процесса.

...