Изучаю многопоточность. Столкнулся со следующей проблемой. Имеется такой вот гипотетический код: Код | 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 отрабатывает в каком-то отдельном потоке/потоках и в консоле я вижу примерно следующее: Как можно заметить, цифры следуют не по порядку. Вопрос такой — Как мне сделать поочередное исполнение потоков строго в той последовательности в которой они создавались? Желательно как можно менее ресурсоемко. Описание кода — в методе Working класса WORK делается какая-то полезная работа, далее результат этой работы посредством делегатов delegWork и delegAnalysis отправляется в анон.метод класса ANALYSIS в котором производится анализ результатов работы класса WORK. Соответсвенно сама работа может выполняться быстрее, чем ее анализ, но сам анализ должен идти строго поочередно друг за другом, а не хаотично. PS. Lock и AutoResetEvent пробовал, но не помогло. Т.к. там доступ/событие получает тот поток, который первый постучался. Соответсвенно стучатся они, опять же, не в том порядке в котором были созданы, а как решит сама система.
|