C #: События & Thread Safe Обновления GUI - PullRequest
3 голосов
/ 29 февраля 2012

Я нахожусь в процессе написания приложения, которое связывается с несколькими устройствами с помощью команд GPIB, выполняя тест на некотором оборудовании.Я установил класс TestProcedure, который запустит новый поток и запустит тестирование.На протяжении всего тестирования я настраивал несколько пользовательских событий для отправки информации обратно в графический интерфейс.Вот пример простого события:

    public event InformationEventHandler<string> TestInfoEvent;
    /// <summary>
    /// Event raised when information should be passed back to the main testing form.
    /// </summary>
    /// <param name="s">Information to send back to form.</param>
    private void OnInfo(string s)
    {
        if (TestInfoEvent != null)
            TestInfoEvent(this, s);
    }

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

TheTestProcedure.TestInfoEvent += new TestProcedure.InformationEventHandler<string> 
                                 (InfoOccurred);
....
private void InfoOccurred(Object sender, string s)
{
    this.textBox1.Text = s + Environment.NewLine + this.textBox1.Text;
    if (this.textBox1.Text.Length > 10000)
        this.textBox1.Text = this.textBox1.Text.Remove(1000);
}

Эта обработка событий, кажется, работает нормально,Я не получил никаких проблем с многопоточностью, и в целом все работает как ожидалось.Тем не менее, в другой форме я только что добавил аналогичный обработчик событий, который генерирует исключение между потоками.Событие запускается, посылая простой класс с небольшим количеством информации, которую я отображаю в InputTextBox (пользовательский элемент управления ComponentOne).У конкретного элемента управления нет метода .Invoke, поэтому я ищу альтернативные решения для асинхронного доступа к нему.

Итак, мой вопрос: безопасны ли обработчики событий для доступа к элементам управления в форме?Если нет, то как запускаются обработчики событий, и может ли кто-нибудь помочь мне обучить или предоставить некоторую связанную информацию о том, как обработчик событий взаимодействует с элементами управления формы?Нужно ли заблокировать событие?

Ответы [ 2 ]

2 голосов
/ 29 февраля 2012

Элементы управления в потоке пользовательского интерфейса могут быть доступны только из потока пользовательского интерфейса - любой доступ из других потоков обязательно вызовет проблемы. Вам нужно использовать InvokeRequired и BeginInvoke(), чтобы маршалировать событие в нужном потоке, если его там еще нет.

Пример

1 голос
/ 29 февраля 2012

Вы захотите создать обратный вызов делегата и Invoke() выполнить его после тестирования свойства InvokeRequired.Следующий код будет обрабатывать добавление потокобезопасным способом.

TheTestProcedure.TestInfoEvent += new TestProcedure.InformationEventHandler<string> 
                             (InfoOccurred);

private void InfoOccurred(Object sender, string s)
{
    LogMessage(s);
}

delegate void LogMessageCallback(string text);

void LogMessage(String message)
{
    if (this.textBox1.InvokeRequired)
        this.Invoke(new LogMessageCallback(LogMessage), message);
    else
    {
        this.textBox1.Text = s + Environment.NewLine + this.textBox1.Text;
        if (this.textBox1.Text.Length > 10000)
            this.textBox1.Text = this.textBox1.Text.Remove(1000);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...