BackgroundWorker vs System.Windows.Forms.Timer
От: jer22  
Дата: 11.01.10 20:36
Оценка:
Доброго времени суток.

Прошу не судить строго, если вопрос покажется глупым, опыта пока маловато...

WinForms, C#. dll-ка (не моя) создаёт потоки (до 50 штук в секунду) в которых вызывает callback-функцию в моём коде и передаёт ей данные. Задача обработать эти данные в основном потоке.

Мысль первая: в callback'е помещать эти данные в очередь и по срабатыванию System.Windows.Forms.Timer (думаю где-то 20мс поставить интервал) проверять очередь и обрабатывать что там накопилось. Не очень нравится что таймер будет всё время крутиться, потому что нашествия потоков случаются время от времени.

Мысль вторая: также с очередью, но создать BackgroundWorker и его DoWork в бесконечном цикле останавливать на EventWaitHandle и по мере поступления данных пропускать его исполнение и создавать событие ProgressChanged в обработчике которого и разбирать данные:


class test
{
        EventWaitHandle wh = new AutoResetEvent(false);
        private BackgroundWorker backgroundWorker1 = new BackgroundWorker();
        object locker = new object();
        Queue<string> tasks = new Queue<string>();

        public test()
        {
            backgroundWorker1.WorkerReportsProgress = true;

            backgroundWorker1.DoWork +=
                new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged +=
                new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

            backgroundWorker1.RunWorkerAsync();
        }

        void Callback(String data)
        {
            lock (locker)
            {
                tasks.Enqueue(data);
                wh.Set();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                lock (locker)
                {
                    if (tasks.Count > 0)
                    {
                        backgroundWorker1.ReportProgress(0);
                    }
                }
                wh.WaitOne();
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lock (locker)
            {
                if (LogWindow.Instance.InvokeRequired)
                {
                }
                while (tasks.Count > 0)
                {
                    parseNewData(tasks.Dequeue());
                }
            }
        }
        
}


Я не знаю как BackgroundWorker проверяет изменение прогресса, если в том же таймере, то конечно мысль глупая. Вообщем посоветуйте как лучше?
Re: BackgroundWorker vs System.Windows.Forms.Timer
От: meerius Канада  
Дата: 11.01.10 22:26
Оценка:
Здравствуйте, jer22, Вы писали:

J>WinForms, C#. dll-ка (не моя) создаёт потоки (до 50 штук в секунду)

Ну, вообще, люди озверели! Может Вам лучше выбросить такую dll-ку?

J>Вообщем посоветуйте как лучше?

Control.Invoke()
«Мы с тобой в чудеса не верим, Оттого их у нас не бывает…»
Re[2]: BackgroundWorker vs System.Windows.Forms.Timer
От: jer22  
Дата: 11.01.10 23:25
Оценка:
Здравствуйте, meerius, Вы писали:

J>>WinForms, C#. dll-ка (не моя) создаёт потоки (до 50 штук в секунду)

M>Ну, вообще, люди озверели! Может Вам лучше выбросить такую dll-ку?
Всё приложение вокруг неё строится и без неё не имеет смысла, альтернатив нет. Да и вообщем я ничего плохого в таком поведении dll не вижу — она получила 50 ответов от сервера, каждый прислала в отдельном потоке, чтоб основной продолжал получать информацию из сети.

J>>Вообщем посоветуйте как лучше?

M>Control.Invoke()
Очень дорогая это штука по ресурсам! Было реализовано и тут же выброшено. У меня сейчас работает код с BackgroundWorker'ом, он едет гораздо лучше.
Re[3]: BackgroundWorker vs System.Windows.Forms.Timer
От: Neco  
Дата: 12.01.10 17:09
Оценка:
Здравствуйте, jer22, Вы писали:

M>>Control.Invoke()

J>Очень дорогая это штука по ресурсам! Было реализовано и тут же выброшено. У меня сейчас работает код с BackgroundWorker'ом, он едет гораздо лучше.
Можете код показать? А как мерили ресурсы?
всю ночь не ем, весь день не сплю — устаю
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.