Принудительно заставить многопоточный класс VB.NET отображать результаты в одной форме.

У меня есть приложение Windows Form, которое использует класс Shared для размещения всех общих объектов приложения. Класс settings имеет коллекцию объектов, которые периодически что-то делают, а затем есть кое-что интересное, они должны предупредить основную форму и обновить ее.

В настоящее время я делаю это через События на объектах, и когда каждый объект создается, я добавляю EventHandler, чтобы отобразить событие обратно в форму. Тем не менее, я сталкиваюсь с некоторыми проблемами, из-за которых эти запросы не всегда попадают в основную копию моей формы. Например, моя форма имеет значок в области уведомлений, но когда форма захватывает и событие и пытается отобразить пузырь, пузырь не появляется. Однако, если я изменю этот код, чтобы сделать значок видимым (хотя он уже есть), а затем отобразить всплывающее окно, появится второй значок и правильно отобразит всплывающее окно.

Кто-нибудь сталкивался с этим раньше? Есть ли способ, которым я могу заставить все свои события быть захваченными одним экземпляром формы, или есть совершенно другой способ справиться с этим? Я могу опубликовать примеры кода, если это необходимо, но я думаю, что это общая проблема с многопоточностью.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: В настоящее время я использую Me.InvokeRequired в обработчике событий в моей форме, и он всегда возвращает FALSE в этом случае. Кроме того, второй значок в трее, созданный, когда я делаю его видимым из этой формы, не имеет контекстного меню, в то время как "реальный" значок имеет - кто-нибудь в этом подсказывает?

Я собираюсь вырвать мои волосы! Это не может быть так сложно!

РЕШЕНИЕ: Спасибо nobugz за подсказку, и это привело меня к коду, который я сейчас использую (который прекрасно работает, хотя я не могу не думать, что есть лучший способ сделать это). Я добавил частную логическую переменную в форму с именем «IsPrimary» и добавил следующий код в конструктор формы:

    Public Sub New()
        If My.Application.OpenForms(0).Equals(Me) Then
            Me.IsFirstForm = True
        End If
    End Sub

Как только эта переменная установлена ​​и конструктор завершает работу, она направляется прямо к обработчику событий, и я имею дело с этим следующим образом (CAVEAT: поскольку искомая форма является основной формой приложения, My.Application.OpenForms ( 0) получает то, что мне нужно. Если бы я искал первый экземпляр не запускаемой формы, мне пришлось бы перебирать, пока я ее не нашел):

    Public Sub EventHandler()
        If Not IsFirstForm Then
            Dim f As Form1 = My.Application.OpenForms(0)
            f.EventHandler()
            Me.Close()
        ElseIf InvokeRequired Then
            Me.Invoke(New HandlerDelegate(AddressOf EventHandler))
        Else
            ' Do your event handling code '
        End If
    End Sub

Во-первых, он проверяет, работает ли он в правильной форме - если нет, тогда вызовите правильную форму. Затем он проверяет правильность потока и вызывает поток пользовательского интерфейса, если это не так. Затем запускается код события. Мне не нравится, что это потенциально три звонка, но я не могу придумать другой способ сделать это. Кажется, это работает хорошо, хотя это немного громоздко. Если у кого-то есть лучший способ сделать это, я хотел бы услышать это!

Еще раз спасибо за помощь - это сводило меня с ума!

Ответы на вопрос(4)

Ваш ответ на вопрос