Почему не срабатывает 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. Может я витиевато изъясняюсь. Забей.


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