#c_sharp #net #многопоточность
Есть модель приложения: объекты-задачи, которые выполняются в бесконечном цикле, информируя об результатах своей работы - пока их не информировали об прекращении работы; элемент пользовательского интерфейса (ЕПИ), который отображает информацию о результатах работы объектов-задач; Вот код объекта-задачи: public class DataItem { public int Index { get; set; } public string Value { get; set; } public object locker { get; set; } } public class Task { private DataItem dataItem { get; set; } public EventWaitHandle local { get; set; } public EventWaitHandle exit { get; set; } Action refreshAction { get; set; } public Task (DataItem dataItem, Action refreshAction, EventWaitHandle localEvent, EventWaitHandle exitEvent) { this.dataItem = dataItem; exit = exitEvent; local = localEvent; this.refreshAction = refreshAction; } public void Procees () { local.WaitOne(); Random n = new Random(); while (!exit.WaitOne(0, false)) { lock (dataItem.locker) { string s = 0.ToString("D10").Remove(dataItem.Index, 1).Insert(dataItem.Index, "x"); dataItem.Index = dataItem.Index == 9 ? 0 : dataItem.Index + 1; dataItem.Value = s; } refreshAction(); Thread.Sleep(n.Next(5, 25) * 100); } local.Set(); } } И вот код "наблюдающего" обьекта: class Main { public EventWaitHandle main = new ManualResetEvent(false); private void create () { main.Reset(); foreach (DataItem item in data) { item.locker = ((ICollection)data).SyncRoot; EventWaitHandle local = new AutoResetEvent(false); EventArray.Add(local); new Thread(new Task(item, RefreshGrid, local, main).Procees).Start(); local.Set(); } foreach (AutoResetEvent are in EventArray) { are.Set(); } } private void stop () { main.Set(); bool l = true; while (l) { AutoResetEvent[] events = EventArray.Cast().ToArray(); l = WaitHandle.WaitAll(events); } } } Объект-задача, помимо сообщения о закрытии работы, сообщает о том, что он остановил работу, что приложению необходимо для нормального закрытия. И вот в чем загвоздка - несмотря на то, что объект-задача получает сообщение о закрытии работы и сообщает об остановке, то главное окно не реагирует на сообщения от задач, это я делаю через l = WaitHandle.WaitAll(events); Почему не реагирует? Может, такой подход неправильный? Что порекомендуете?
Ответы
Ответ 1
Когда вы делаете WaitAll - вы блокируете вызывающий поток (в котором GUI). Поэтому окно ни на что не реагирует. Уберите отслеживание состояния и ожидания в фоновый поток, а в GUI только отображайте состояние и передавайте команды.
Комментариев нет:
Отправить комментарий