Есть модель приложения:
объекты-задачи, которые выполняются в бесконечном цикле, информируя об результатах своей работы - пока их не информировали об прекращении работы;
элемент пользовательского интерфейса (ЕПИ), который отображает информацию о результатах работы объектов-задач;
Вот код объекта-задачи:
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
Объект-задача, помимо сообщения о закрытии работы, сообщает о том, что он остановил работу, что приложению необходимо для нормального закрытия. И вот в чем загвоздка - несмотря на то, что объект-задача получает сообщение о закрытии работы и сообщает об остановке, то главное окно не реагирует на сообщения от задач, это я делаю через
l = WaitHandle.WaitAll(events);
Почему не реагирует? Может, такой подход неправильный? Что порекомендуете?
Ответ
Когда вы делаете WaitAll - вы блокируете вызывающий поток (в котором GUI). Поэтому окно ни на что не реагирует. Уберите отслеживание состояния и ожидания в фоновый поток, а в GUI только отображайте состояние и передавайте команды.
Комментариев нет:
Отправить комментарий