Потокобезопасные вызовы формы Windows замораживают приложение - PullRequest
0 голосов
/ 22 декабря 2011

У меня есть проект обработки исключений в моем приложении, который можно вызвать из любого места, чтобы показать пользователю, что есть проблема с системой. Все отлично работает, когда вызов сделан откуда-то в пользовательском интерфейсе, как и ожидалось. Когда я звоню из частей приложения без интерфейса, все зависает. У меня есть код, завернутый в потоки безопасных вызовов, и при переходе через них они не требуют вызова Invoke. Любая помощь очень ценится. Код ниже:

Внутри формы

    void err_DispEvent(string text)
    {
        if (InvokeRequired)
        {
            Invoke(new Error.DisplayDelegate(err_DispEvent), new object [] {text});
        }
        else
        {
            this.Show();
        }        
    }

Звонок из класса

public void FaultError(string errorMsg)
    {
        FaultForm fform = new FaultForm(errorMsg, "Internal Fault");
        if (this.dispEvent != null)
        {
            dispEvent(errorMsg);
        }
    }

    public event DisplayDelegate DispEvent
    {
        add { dispEvent += value; }
        remove { dispEvent -= value; }
    }

    private event DisplayDelegate dispEvent;

    public delegate void DisplayDelegate(string text);

Пример использования класса в приложении

ECDUExceptions.Error newError = ECDUExceptions.Error.getInstance();
newError.FaultError("Heater is not responding to function calls, it has been turned off");

Ответы [ 3 ]

2 голосов
/ 22 декабря 2011

Некоторая информация при повторном вызове методов:

  1. Используйте BeginInvoke(...) вместо Invoke(...), так как это не будет ждать завершения вызова, и поэтому не остановитвызывающий поток.

  2. Используйте Action при повторном вызове.Так что в вашем случае вы можете изменить свой вызов на:

    BeginInvoke(new Action<string>(err_DispEvent), text);
    
1 голос
/ 22 декабря 2011

Используйте BeginInvoke (...) вместо Invoke (...).Это поместит ваш запрос в конец очереди

0 голосов
/ 22 декабря 2011

Создайте какую-либо очередь для сообщений, которые должны отображаться.

Заполните очередь из любого потока, который вам требуется.

Из графического интерфейса, отвечающего за отображение сообщений, используйте таймерснять и показать их.

Упрощенно, но будет работать без особых усилий.И вам не нужно ничего вызывать (Invoke ()), поскольку Forms.Timer работает в цикле сообщений пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...