Re[5]: Почему не срабатывает RunWorkerCompleted?
От: drol  
Дата: 05.08.09 06:31
Оценка: 1 (1) +1
Здравствуйте, indusov.net, Вы писали:

IN>При завершении чего?


При завершении приложения.

IN>Он канселит обработку, после чего должен вызваться RunWorkerCompleted.


Cancelling в BackgroundWorker'е — всего лишь взведение соответствующего флажка. Исполнение DoWork никто не прерывает. Если хочется реального cancelling'а, то его нужно делать ручками в DoWork. Ничего подобного в коде топикстартера не наблюдается — его DoWork будет молотить до победы.
Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 04.08.09 16:30
Оценка:
using System;
using System.ComponentModel ;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;

using Retriever.Interface;

namespace Retriever
{
    class Program
    {
        static IRetriever cls;

        static void Main(string[] args)
        {
            cls = new RetrieverMainClass();
            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerSupportsCancellation = true;
            

            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.RunWorkerAsync();
            Console.WriteLine("Press ENTER to exit...");
            Console.ReadLine();
            bw.CancelAsync();
            Thread.Sleep(5000);
        }

        static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled )
                cls.Suspend ();
        }

        static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            foreach (string s in cls.GetURLS())
                Console.WriteLine(s);
        }
    }
}


Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?
Re: Почему не срабатывает RunWorkerCompleted?
От: bxt Россия indusov.net
Дата: 04.08.09 16:49
Оценка:
Здравствуйте, senglory, Вы писали:


S>
S>using System;
S>using System.ComponentModel ;
S>using System.Collections.Generic;
S>using System.Linq;
S>using System.Text;
S>using System.Threading;
S>using System.Reflection;

S>using Retriever.Interface;

S>namespace Retriever
S>{
S>    class Program
S>    {
S>        static IRetriever cls;

S>        static void Main(string[] args)
S>        {
S>            cls = new RetrieverMainClass();
S>            BackgroundWorker bw = new BackgroundWorker();
S>            bw.WorkerSupportsCancellation = true;
            

S>            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
S>            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
S>            bw.RunWorkerAsync();
S>            Console.WriteLine("Press ENTER to exit...");
S>            Console.ReadLine();
S>            bw.CancelAsync();
S>            Thread.Sleep(5000);
S>        }

S>        static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
S>        {
S>            if (e.Cancelled )
S>                cls.Suspend ();
S>        }

S>        static void bw_DoWork(object sender, DoWorkEventArgs e)
S>        {
S>            foreach (string s in cls.GetURLS())
S>                Console.WriteLine(s);
S>        }
S>    }
S>}

S>


S>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


Мне кажется он у тебя вызывается до того как ты на Enter нажал.

:from Reflector
private void WorkerThreadStart(object argument)
{
object result = null;
Exception error = null;
bool cancelled = false;
try
{
DoWorkEventArgs e = new DoWorkEventArgs(argument);
this.OnDoWork(e); // тут твой хандлер
if (e.Cancel)
{
cancelled = true;
}
else
{
result = e.Result;
}
}
catch (Exception exception2)
{
error = exception2;
}
RunWorkerCompletedEventArgs arg = new RunWorkerCompletedEventArgs(result, error, cancelled);
this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg);
}
Re[2]: Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 04.08.09 17:04
Оценка:
Здравствуйте, bxt, Вы писали:

bxt>Здравствуйте, senglory, Вы писали:



S>>
S>>using System;
S>>using System.ComponentModel ;
S>>using System.Collections.Generic;
S>>using System.Linq;
S>>using System.Text;
S>>using System.Threading;
S>>using System.Reflection;

S>>using Retriever.Interface;

S>>namespace Retriever
S>>{
S>>    class Program
S>>    {
S>>        static IRetriever cls;

S>>        static void Main(string[] args)
S>>        {
S>>            cls = new RetrieverMainClass();
S>>            BackgroundWorker bw = new BackgroundWorker();
S>>            bw.WorkerSupportsCancellation = true;
            

S>>            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
S>>            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
S>>            bw.RunWorkerAsync();
S>>            Console.WriteLine("Press ENTER to exit...");
S>>            Console.ReadLine();
S>>            bw.CancelAsync();
S>>            Thread.Sleep(5000);
S>>        }

S>>        static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
S>>        {
S>>            if (e.Cancelled )
S>>                cls.Suspend ();
S>>        }

S>>        static void bw_DoWork(object sender, DoWorkEventArgs e)
S>>        {
S>>            foreach (string s in cls.GetURLS())
S>>                Console.WriteLine(s);
S>>        }
S>>    }
S>>}

S>>


S>>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


bxt>Мне кажется он у тебя вызывается до того как ты на Enter нажал.


bxt>:from Reflector

bxt>private void WorkerThreadStart(object argument)
bxt>{
bxt> object result = null;
bxt> Exception error = null;
bxt> bool cancelled = false;
bxt> try
bxt> {
bxt> DoWorkEventArgs e = new DoWorkEventArgs(argument);
bxt> this.OnDoWork(e); // тут твой хандлер
bxt> if (e.Cancel)
bxt> {
bxt> cancelled = true;
bxt> }
bxt> else
bxt> {
bxt> result = e.Result;
bxt> }
bxt> }
bxt> catch (Exception exception2)
bxt> {
bxt> error = exception2;
bxt> }
bxt> RunWorkerCompletedEventArgs arg = new RunWorkerCompletedEventArgs(result, error, cancelled);
bxt> this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg);
bxt>}



Исключено. GetURLS() — это минут на 10 вызов, а я рву сразу как т-ко увижу "Press ENTER"
Re[3]: Почему не срабатывает RunWorkerCompleted?
От: bxt Россия indusov.net
Дата: 04.08.09 17:07
Оценка:
Здравствуйте, senglory, Вы писали:

S>Здравствуйте, bxt, Вы писали:


bxt>>Здравствуйте, senglory, Вы писали:


S>>>[c#]

S>>>using System;
S>>>using System.ComponentModel ;

S>Исключено. GetURLS() — это минут на 10 вызов, а я рву сразу как т-ко увижу "Press ENTER"


Чудес не бывает
Re[4]: Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 04.08.09 17:27
Оценка:
Здравствуйте, bxt, Вы писали:

bxt>Здравствуйте, senglory, Вы писали:


S>>Здравствуйте, bxt, Вы писали:


bxt>>>Здравствуйте, senglory, Вы писали:


S>>>>[c#]

S>>>>using System;
S>>>>using System.ComponentModel ;

S>>Исключено. GetURLS() — это минут на 10 вызов, а я рву сразу как т-ко увижу "Press ENTER"


bxt>Чудес не бывает


Но тут именно что непонятная хрень АКА чудо. Проверял 100 раз, GetURLS() работает долго и никаких исключений он не бросает.
Re[5]: Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 04.08.09 20:39
Оценка:
Здравствуйте, senglory, Вы писали:

S>Здравствуйте, bxt, Вы писали:


bxt>>Здравствуйте, senglory, Вы писали:


S>>>Здравствуйте, bxt, Вы писали:


bxt>>>>Здравствуйте, senglory, Вы писали:


S>>>>>
S>>>>>using System;
S>>>>>using System.ComponentModel ;

S>>>Исключено. GetURLS() - это минут на 10 вызов, а я рву сразу как т-ко увижу "Press ENTER"

bxt>>Чудес не бывает :)

S>Но тут именно что непонятная хрень АКА чудо. Проверял 100 раз, GetURLS() работает долго и никаких исключений он не бросает.

Заменил bw_DoWork()

на


[c#]
        static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10000; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(i);
            }
        }


тоже самое.
Re: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 04.08.09 21:11
Оценка:
Здравствуйте, senglory, Вы писали:

S>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


Возможно я знаю в чем фишка.
Попробу-ка переписать main так:

        static void Main(string[] args)
        {
            Thread th = new Thread(delegate(){
            cls = new RetrieverMainClass();
            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerSupportsCancellation = true;
            

            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.RunWorkerAsync();
            Console.WriteLine("Press ENTER to exit...");
            Console.ReadLine();
            bw.CancelAsync();
            Thread.Sleep(5000);
            });
            th.Start();
            th.Join();
        }


Если сработает ответ такой (большое ИМХО) — событие RunWorkerCompleted не файрится потому что оно хитро выполняется только на главном UIном треде, а если воркер сам на нем, то ты можешь все обновления UI делать из ProgressChanged и DoWork и RunWorkerCompleted вызван не будет.
Re[2]: Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 04.08.09 21:40
Оценка:
Здравствуйте, indusov.net, Вы писали:

IN>Здравствуйте, senglory, Вы писали:


S>>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


IN>Возможно я знаю в чем фишка.

IN>Попробу-ка переписать main так:

IN>
IN>        static void Main(string[] args)
IN>        {
IN>            Thread th = new Thread(delegate(){
IN>            cls = new RetrieverMainClass();
IN>            BackgroundWorker bw = new BackgroundWorker();
IN>            bw.WorkerSupportsCancellation = true;
            

IN>            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
IN>            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
IN>            bw.RunWorkerAsync();
IN>            Console.WriteLine("Press ENTER to exit...");
IN>            Console.ReadLine();
IN>            bw.CancelAsync();
IN>            Thread.Sleep(5000);
IN>            });
IN>            th.Start();
IN>            th.Join();
IN>        }
IN>


IN>Если сработает ответ такой (большое ИМХО) — событие RunWorkerCompleted не файрится потому что оно хитро выполняется только на главном UIном треде, а если воркер сам на нем, то ты можешь все обновления UI делать из ProgressChanged и DoWork и RunWorkerCompleted вызван не будет.



Не помогло, увы ЧТо за фигня с этим BackgroundWorker
Re[3]: Почему не срабатывает RunWorkerCompleted?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.08.09 22:27
Оценка:
Здравствуйте, senglory, Вы писали:

Следует цитировать только то, что необходимо.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[2]: Почему не срабатывает RunWorkerCompleted?
От: drol  
Дата: 05.08.09 04:29
Оценка:
Здравствуйте, indusov.net, Вы писали:

IN>Если сработает ответ такой (большое ИМХО) — событие RunWorkerCompleted не файрится потому что оно хитро выполняется только на главном UIном треде


Поток обработки UI-событий здесь совершенно не при делах. Вызов RunWorkerCompleted происходит через ThreadPool.QueueUserWorkItem()
Re: Почему не срабатывает RunWorkerCompleted?
От: drol  
Дата: 05.08.09 04:43
Оценка:
Здравствуйте, senglory, Вы писали:

S>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


Потому что размещение вызова RunWorkerCompleted происходит после того как отработает DoWork. А так как, по Вашим словам, он парит голову ажно 10 минут, и кнопку Вы жмёте сразу, то, естественно, никакого RunWorkerCompleted Вы не увидите, бо приложение уже завершилось.
Re[2]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 05:47
Оценка:
Здравствуйте, drol, Вы писали:

D>Здравствуйте, senglory, Вы писали:


S>>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


D>Потому что размещение вызова RunWorkerCompleted происходит после того как отработает DoWork. А так как, по Вашим словам, он парит голову ажно 10 минут, и кнопку Вы жмёте сразу, то, естественно, никакого RunWorkerCompleted Вы не увидите, бо приложение уже завершилось.


Если посмотреть WorkerThreadStart, который проскакивал тут ранее, видно что this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg) вызывается при любом раскладе, даже если произошла ошибка.
Re[3]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 05:49
Оценка:
Здравствуйте, indusov.net, Вы писали:

IN>Здравствуйте, drol, Вы писали:


D>>Здравствуйте, senglory, Вы писали:


S>>>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?


Вот до студии доберусь и сразу скажу где собак зарыт, гадать надоело.
Re[3]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 05:52
Оценка:
Здравствуйте, drol, Вы писали:

D>Здравствуйте, indusov.net, Вы писали:


IN>>Если сработает ответ такой (большое ИМХО) — событие RunWorkerCompleted не файрится потому что оно хитро выполняется только на главном UIном треде

D>Поток обработки UI-событий здесь совершенно не при делах. Вызов RunWorkerCompleted происходит через ThreadPool.QueueUserWorkItem()

Сорри, имелся ввиду тред на котором Main выполняется.
Re[3]: Почему не срабатывает RunWorkerCompleted?
От: drol  
Дата: 05.08.09 05:58
Оценка:
Здравствуйте, indusov.net, Вы писали:

IN>Если посмотреть WorkerThreadStart, который проскакивал тут ранее, видно что this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg) вызывается при любом раскладе, даже если произошла ошибка.


Он вызывается после отработки DoWork. У топикстартера же DoWork работает 10 минут, а приложение завершается уже через 5 секунд. При завершении все background-потоки CLR тупо пристреливает. Причём тут какие-то ошибки ???
Re[4]: Почему не срабатывает RunWorkerCompleted?
От: drol  
Дата: 05.08.09 06:02
Оценка:
Здравствуйте, indusov.net, Вы писали:

IN>Сорри, имелся ввиду тред на котором Main выполняется.


Легче не стало Главный поток приложения никакого отношения к ThreadPool'у также не имеет.
Re[5]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 06:09
Оценка:
Здравствуйте, drol, Вы писали:

D>Здравствуйте, indusov.net, Вы писали:


IN>>Сорри, имелся ввиду тред на котором Main выполняется.


D>Легче не стало Главный поток приложения никакого отношения к ThreadPool'у также не имеет.


!пт, инстанс BackgroundWorker где создан?

P.S. Может я витиевато изъясняюсь. Забей.
Re[4]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 06:14
Оценка:
Здравствуйте, drol, Вы писали:

D>Здравствуйте, indusov.net, Вы писали:


IN>>Если посмотреть WorkerThreadStart, который проскакивал тут ранее, видно что this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg) вызывается при любом раскладе, даже если произошла ошибка.


D>Он вызывается после отработки DoWork. У топикстартера же DoWork работает 10 минут, а приложение завершается уже через 5 секунд. При завершении все background-потоки CLR тупо пристреливает. Причём тут какие-то ошибки ???


При завершении чего?
Он канселит обработку, после чего должен вызваться RunWorkerCompleted.

MSDN: Occurs when the background operation has completed, has been canceled, or has raised an exception.
Re: Почему не срабатывает RunWorkerCompleted?
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 05.08.09 06:19
Оценка:
Здравствуйте, senglory, Вы писали:

Операция BackgroundWorker-а сама собой прервана быть не может. Корректный код приведен ниже. Если нужна более подробная информация, можно почитать Прерывание операции в BackgroundWorker.

var bw = new BackgroundWorker();

bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;

bw.DoWork += (o, e) =>
{
    Console.WriteLine("{0}: Starting long running task", 
        DateTime.Now.TimeOfDay);
    //Doing long running task
    for (int i = 0; i < 10; i++)
    {
        //We can split our task in multiple stages
        Thread.Sleep(TimeSpan.FromSeconds(1));
        bw.ReportProgress((i + 1) * 10);
        if (bw.CancellationPending)
        {
            //user canceled our task
            Console.WriteLine("{0}: Task cancelled", 
                DateTime.Now.TimeOfDay);
            break;
        }
    }
    
    Console.WriteLine("{0}: Finishing long running task", 
        DateTime.Now.TimeOfDay);
};

bw.ProgressChanged += (o, e) =>
{
    //Processing progress
    Console.WriteLine("{0}: Progress changed. Percentage: {1}", 
        DateTime.Now.TimeOfDay, e.ProgressPercentage);
};

bw.RunWorkerCompleted += (o, e) =>
{
    //Handling worker complete event
    if (e.Cancelled)
        Console.WriteLine("{0}: Long running task cancelled", 
            DateTime.Now.TimeOfDay);
    else if (e.Error != null)
        Console.WriteLine("{0}: Long running task failed. Error: {1}", 
            DateTime.Now.TimeOfDay, e.Error);
    else
        Console.WriteLine("{0}: Long running task finished successfully", 
            DateTime.Now.TimeOfDay);
};

//Starting long running task
bw.RunWorkerAsync();

Console.ReadLine();
//If we still running our task, trying to cancel it
if (bw.IsBusy)
    bw.CancelAsync();
Console.ReadLine();
Re[6]: Почему не срабатывает RunWorkerCompleted?
От: drol  
Дата: 05.08.09 06:22
Оценка:
Здравствуйте, indusov.net, Вы писали:

IN>>>Сорри, имелся ввиду тред на котором Main выполняется.


D>>Легче не стало Главный поток приложения никакого отношения к ThreadPool'у также не имеет.


IN>!пт, инстанс BackgroundWorker где создан?


А какая разница ??? DoWork запускается через BeginInvoke() его типа-делегата. RunWorkerCompleted через ThreadPool. Причём тут поток создатель BackgroundWorker'а ???

IN>P.S. Может я витиевато изъясняюсь. Забей.


Вы просто не понимаете как работает механизма.
Re[7]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 10:10
Оценка:
Здравствуйте, drol, Вы писали:

D>Вы просто не понимаете как работает механизма.

Чукча не читатель, чукча писатель.
Re[6]: Почему не срабатывает RunWorkerCompleted?
От: Аноним  
Дата: 05.08.09 10:21
Оценка:
Здравствуйте, drol, Вы писали:

D>Здравствуйте, indusov.net, Вы писали:


IN>>При завершении чего?

D>При завершении приложения.
IN>>Он канселит обработку, после чего должен вызваться RunWorkerCompleted.
D>Cancelling в BackgroundWorker'е — всего лишь взведение соответствующего флажка. Исполнение DoWork никто не прерывает. Если хочется реального cancelling'а, то его нужно делать ручками в DoWork. Ничего подобного в коде топикстартера не наблюдается — его DoWork будет молотить до победы.

Да, 15 секунд отладки кода топикстартера показали твою правоту
После CancelAsync мы успешно продолжаем приходить в DoWork.


http://www.developerdotstar.com/community/node/671
Re[6]: Почему не срабатывает RunWorkerCompleted?
От: indusov.net Россия indusov.net
Дата: 05.08.09 10:25
Оценка:
Здравствуйте, drol, Вы писали:

D>Cancelling в BackgroundWorker'е — всего лишь взведение соответствующего флажка. Исполнение DoWork никто не прерывает. Если хочется реального cancelling'а, то его нужно делать ручками в DoWork. Ничего подобного в коде топикстартера не наблюдается — его DoWork будет молотить до победы.


Да, 15 секунд отладки кода топикстартера показали твою правоту
После CancelAsync мы успешно продолжаем приходить в DoWork.


http://www.developerdotstar.com/community/node/671
Re: Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 05.08.09 15:15
Оценка:
В общем, ответ нашелся:


static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10000; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine(i);
                if (bw.CancellationPending )
                {
                    e.Result = "done";
                    return ;
                }
            }
        }



И все нормально прерывается!
Re[2]: Почему не срабатывает RunWorkerCompleted?
От: senglory  
Дата: 05.08.09 18:40
Оценка:
Вот только как бы сделать уведомление о прерывании треда, если тред исполняет одну долгоиграющую функцию, к-рая не может ничего знать о CancellationPending и пр. деталях ее вызова? Не важно , как это сделать — без BackgroundWorker или с ним.
Re[3]: Почему не срабатывает RunWorkerCompleted?
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 06.08.09 07:18
Оценка:
Здравствуйте, senglory, Вы писали:

S>Вот только как бы сделать уведомление о прерывании треда, если тред исполняет одну долгоиграющую функцию, к-рая не может ничего знать о CancellationPending и пр. деталях ее вызова? Не важно , как это сделать — без BackgroundWorker или с ним.


Еще раз повторюсь. Почитай здесь. Здесь же именно твой случай и расписывается.


public class AbortableBackgroundWorker : BackgroundWorker
{
    private Thread workerThread;
 
    protected override void OnDoWork(DoWorkEventArgs e)
    {
        workerThread = Thread.CurrentThread;
        try
        {
            base.OnDoWork(e);
        }
        catch (ThreadAbortException)
        {
            e.Cancel = true; //We must set Cancel property to true!
            Thread.ResetAbort(); //Prevents ThreadAbortException propagation
        }
    }
 
    public void Abort()
    {
        if (workerThread != null)
        {
            workerThread.Abort();
            workerThread = null;
        }
    }
}



Основная работа делается в переопределенном методе OnDoWork, который уже вызывается в потоке пула потоков (т.к. реализация класса BackgroundWorker основана на пуле потоков). В этом методе запоминается поток, выполняющий текущую операцию, и в методе Abort вызывается метод Abort этого потока.

Прерывание потока путем вызова метода Thread.Abort имеет некоторые особенности, которые нужно учитывать, как при реализации класса AbortableBackgroundWorker, так и его клиентов. Исключение ThreadAbortException является особенным типом исключения, которое трактуется CLR особым образом. Основная особенность в том, что после выполнения блоков catch и finally никакой код выполняться не будет, а учитывая, что прерываемый поток является потоком из пула потоков, то ни к чему хорошему это не приведет. Именно поэтому в обработчике исключения ThreadAbortException метода OnDoWork вызывается метод Thread.ResetAbort, который предотвращает распространение исключения ThreadAbortException и выполнения потока продолжается, но уже не с того места, где он выполнялся (в середине длительной операции), а так, как будто асинхронная операция успешно завершилась.

На клиентов класса AbortableBackgroundWorker, также налагаются некоторые ограничения, связанной с прерыванием рабочего потока. Во-первых, если обработчик события DoWork содержит обработку исключения, то там должно быть дополнительный блок catch для исключения ThreadAbortException, который обрабатывать на этом уровне не нужно. Во-вторых, исключение ThreadAbortException относится к асинхронным исключениями, которые могут возникнуть в любой точке управляемого кода, что может привести к непредвиденным последствиям и рассогласованному состоянию приложения. Например, если будет прерван поток, выполняющий статический конструктор некоторого класса, то последующее обращение к этому классу также будет приводить к генерации исключения TypeLoadException. В-третьих, CLR не всегда сможет прервать выполнение потока. Так, например, прерывание потока будет невозможно, если поток выполняет неуправляемый код или блоки catch/finally управляемого кода.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.