Я пытаюсь поддерживать какой-то ужасный VB для получения параллелизма.
Я хочу делегировать некоторый математический код потоку и вызвать его с EventArgs, который содержит структуру с информацией, с которойобновить форму.В обработчике событий пользовательского интерфейса я использую BeginInvoke, чтобы не блокировать поток, поскольку обновление пользовательского интерфейса занимает довольно много времени, но поток должен продолжить работу со следующим набором математических операций.
Предыдущий программист реализовал таймер для вызова кода Maths, и существует множество глобальных переменных, представляющих результаты;я никак не могу реализовать блокировку данных, это слишком большое изменение.Проблема с решением для таймера заключается в том, что код Maths не может работать во время обновления пользовательского интерфейса (с меньшей скоростью).Я также рассмотрел возможность разделения кода пользовательского интерфейса по многим событиям таймера, но это также весьма утомительно, чтобы добиться баланса между циклами.
Безопасен ли поток EventArgs, т. Е. Если пользовательский интерфейс начинает использовать переданныйEventArgs и поток генерирует другое событие, ИЛИ должен ли пользовательский интерфейс клонировать копию перед передачей управления потоку пользовательского интерфейса?
Я написал тестовый код, который выглядит следующим образом.
Private Observed As UIDelegatePattern.Observed
Private Delegate Sub ProcessDelegate(ByVal sender As Object, ByVal e As UIDelegatePattern.Observed.ProcessEventArgs)
Private Sub Render(ByVal sender As Object, ByVal e As UIDelegatePattern.Observed.ProcessEventArgs)
If Me.InvokeRequired Then
Dim d As ProcessDelegate = New ProcessDelegate(AddressOf Render)
' invoke on the UI thread asynchronously
Me.BeginInvoke(d, New Object() {sender, e})
Else
' prevent event overflow by removing the handler before the long rendering activity
RemoveHandler Observed.EventHandler, AddressOf Render
' simulate many controls updates
For i As Integer = 0 To 1000
Me.Label1.Text = e.Message
Next
Me.Update()
Me.Refresh()
Application.DoEvents()
' add the handler back in for next time
AddHandler Observed.EventHandler, AddressOf Render
End If
End Sub