Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как на C# запустить поочередно несколько потоков? 
:(
    Опции темы
SuprSonic
Дата 16.1.2019, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Изучаю многопоточность. Столкнулся со следующей проблемой. Имеется такой вот гипотетический код:
Код

public class WORK{
        private int number;
        public Action<int> delegWork; // Обобщ.делегат
 
        public void Working(int num){
                this.number += num; // Какая-то полезная работа с результатов переданным в this.number
                ThreadPool.QueueUserWorkItem((object n) => { this.delegWork((int)n); }, this.number ); //Запуск делегата
        }
}
 
public class ANALYSIS{
        private readonly Form _form;  // Windows Form
        public Action<int> delegAnalysis; // Обобщ.делегат
 
        public ANALYSIS(Form form){
                this._form = form;
                this.Make();
        }
        
        // Метод класса, в котором происходит присвоение делегату анон.метода
        private void Make(){
                this.delegAnalysis += (number) => {
                      this._form.Invoke((MethodInvoker)delegate{
                           Thread.Sleep(25);  // Эмуляция полезной работы
                           Console.WriteLine ("Number: " + number);
                      });
                };
        }        
}
.....
 
/* В основном потоке */
 
WORK worker = new WORK();
ANALYSIS analyzer = new ANALYSIS(this); // В конструктор передаем текущий Windows Form приложения 
 
 
worker.delegWork += (number) => { analyzer.delegAnalysis(number); };
 
//Цикл в основном потоке (например построчное чтение из файла и т.п.)
for(int i = 0; i < 500; i++){
        worker.Working(i);
}


Многопоточность реализовал с помощью ThreadPool.QueueUserWorkItem т.к. он более экономичный. В данном случаем Console.WriteLine отрабатывает в каком-то отдельном потоке/потоках и в консоле я вижу примерно следующее:

Код

1
3
6
4
2
5
...
500
489
499


Как можно заметить, цифры следуют не по порядку.

Вопрос такой  — Как мне сделать поочередное исполнение потоков строго в той последовательности в которой они создавались? Желательно как можно менее ресурсоемко.

Описание кода — в методе Working класса WORK делается какая-то полезная работа, далее результат этой работы посредством делегатов delegWork и delegAnalysis отправляется в анон.метод класса ANALYSIS в котором производится анализ результатов работы класса WORK. Соответсвенно сама работа может выполняться быстрее, чем ее анализ, но сам анализ должен идти строго поочередно друг за другом, а не хаотично. 

PS. Lock и AutoResetEvent пробовал, но не помогло. Т.к. там доступ/событие получает тот поток, который первый постучался. Соответсвенно стучатся они, опять же, не в том порядке в котором были созданы, а как решит сама система.
PM MAIL   Вверх
SuprSonic
Дата 16.1.2019, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



На данный момент нашел такое решение с использованием BlockingCollection и запуском второго потока в конструкторе при инициализации WORK. Из небольших минусов, это всегда запущенный второй поток. Кто предложит улучшение данного кода?  smile 
Код

public class WORK{
        private BlockingCollection<Func<Task>> _collection = new BlockingCollection<Func<Task>>();
        private Thread ConsumerThread;
 
        private int number;
        public Action<int> delegWork; // Обобщ.делегат
        
        //Конструктор
        public WORK(){
                this.ConsumerThread = new Thread(this.LaunchThread);
                this.ConsumerThread.Start();
        }
 
        public void Working(int num){
                this.number += num; // Какая-то полезная работа с результатов переданным в this.number
                int index = this.number; this._collection.Add(new Func<Task>(async () => { this.delegWork(index); })); // Добавляем делегат во второй поток через BlockingCollection
        }
        
        // Метод для второго потока 
        private async void LaunchThread()
        {
            while (true)
            {
                var processTask = this._collection.Take();
                await Task.Run(processTask);
            }
        }
}
 
public class ANALYSIS{
        private readonly Form _form;  // Windows Form
        public Action<int> delegAnalysis; // Обобщ.делегат
 
        public ANALYSIS(Form form){
                this._form = form;
                this.Make();
        }
        
        // Метод класса, в котором происходит присвоение делегату анон.метода
        private void Make(){
                this.delegAnalysis += (number) => {
                      this._form.Invoke((MethodInvoker)delegate{
                           Console.WriteLine ("Number in analyzer: " + number);
                      });
                };
        }        
}
.....
 
/* В основном потоке */
 
WORK worker = new WORK();
ANALYSIS analyzer = new ANALYSIS(this); // В конструктор передаем текущий Windows Form приложения 

//Подписываем делегат
worker.delegWork += (number) => { analyzer.delegAnalysis(number); };
worker.delegWork += (number) => { Console.WriteLine ("Number: " + number); };
 
//Второй поток для задачи (например построчное чтение из файла и т.п.)
new Thread(() =>
{
     for(int i = 0; i < 500; i++) worker.Working(i);
}).Start();

PM MAIL   Вверх
Google
  Дата 22.10.2019, 22:04 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0860 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.