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 не вызовется. Почему?
Здравствуйте, senglory, Вы писали:
S>Здравствуйте, bxt, Вы писали:
bxt>>Здравствуйте, senglory, Вы писали:
S>>>[c#] S>>>using System; S>>>using System.ComponentModel ;
S>Исключено. GetURLS() — это минут на 10 вызов, а я рву сразу как т-ко увижу "Press ENTER"
Здравствуйте, bxt, Вы писали:
bxt>Здравствуйте, senglory, Вы писали:
S>>Здравствуйте, bxt, Вы писали:
bxt>>>Здравствуйте, senglory, Вы писали:
S>>>>[c#] S>>>>using System; S>>>>using System.ComponentModel ;
S>>Исключено. GetURLS() — это минут на 10 вызов, а я рву сразу как т-ко увижу "Press ENTER"
bxt>Чудес не бывает
Но тут именно что непонятная хрень АКА чудо. Проверял 100 раз, GetURLS() работает долго и никаких исключений он не бросает.
Здравствуйте, 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);
}
}
Здравствуйте, 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 вызван не будет.
Здравствуйте, 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
Здравствуйте, indusov.net, Вы писали:
IN>Если сработает ответ такой (большое ИМХО) — событие RunWorkerCompleted не файрится потому что оно хитро выполняется только на главном UIном треде
Поток обработки UI-событий здесь совершенно не при делах. Вызов RunWorkerCompleted происходит через ThreadPool.QueueUserWorkItem()
Здравствуйте, senglory, Вы писали:
S>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?
Потому что размещение вызова RunWorkerCompleted происходит после того как отработает DoWork. А так как, по Вашим словам, он парит голову ажно 10 минут, и кнопку Вы жмёте сразу, то, естественно, никакого RunWorkerCompleted Вы не увидите, бо приложение уже завершилось.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, senglory, Вы писали:
S>>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?
D>Потому что размещение вызова RunWorkerCompleted происходит после того как отработает DoWork. А так как, по Вашим словам, он парит голову ажно 10 минут, и кнопку Вы жмёте сразу, то, естественно, никакого RunWorkerCompleted Вы не увидите, бо приложение уже завершилось.
Если посмотреть WorkerThreadStart, который проскакивал тут ранее, видно что this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg) вызывается при любом раскладе, даже если произошла ошибка.
Здравствуйте, indusov.net, Вы писали:
IN>Здравствуйте, drol, Вы писали:
D>>Здравствуйте, senglory, Вы писали:
S>>>Если нажать ENTER, то bw_RunWorkerCompleted не вызовется. Почему?
Вот до студии доберусь и сразу скажу где собак зарыт, гадать надоело.
Здравствуйте, drol, Вы писали:
D>Здравствуйте, indusov.net, Вы писали:
IN>>Если сработает ответ такой (большое ИМХО) — событие RunWorkerCompleted не файрится потому что оно хитро выполняется только на главном UIном треде D>Поток обработки UI-событий здесь совершенно не при делах. Вызов RunWorkerCompleted происходит через ThreadPool.QueueUserWorkItem()
Сорри, имелся ввиду тред на котором Main выполняется.
Здравствуйте, indusov.net, Вы писали:
IN>Если посмотреть WorkerThreadStart, который проскакивал тут ранее, видно что this.asyncOperation.PostOperationCompleted(this.operationCompleted, arg) вызывается при любом раскладе, даже если произошла ошибка.
Он вызывается после отработки DoWork. У топикстартера же DoWork работает 10 минут, а приложение завершается уже через 5 секунд. При завершении все background-потоки CLR тупо пристреливает. Причём тут какие-то ошибки ???
Здравствуйте, drol, Вы писали:
D>Здравствуйте, indusov.net, Вы писали:
IN>>Сорри, имелся ввиду тред на котором Main выполняется.
D>Легче не стало Главный поток приложения никакого отношения к ThreadPool'у также не имеет.
Здравствуйте, 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.
Операция 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 taskfor (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 eventif (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 itif (bw.IsBusy)
bw.CancelAsync();
Console.ReadLine();
Здравствуйте, indusov.net, Вы писали:
IN>>>Сорри, имелся ввиду тред на котором Main выполняется.
D>>Легче не стало Главный поток приложения никакого отношения к ThreadPool'у также не имеет.
IN>!пт, инстанс BackgroundWorker где создан?
А какая разница ??? DoWork запускается через BeginInvoke() его типа-делегата. RunWorkerCompleted через ThreadPool. Причём тут поток создатель BackgroundWorker'а ???
IN>P.S. Может я витиевато изъясняюсь. Забей.