0

Я хочу выставить метод для обновления текстового поля с сообщениями в виде журнала состояния. Я хотел бы использовать метод AppendText, но при использовании этой проблемы у меня возникает странная проблема с несколькими потоками. Я могу добавлять новые сообщения путем конкатенации просто отлично. Проблема представляет собой «я», поскольку текстовое поле не отображается, а затем при закрытии формы появляется ошибка доступа к перекрестному потоку. Вот примеры того, что работает, а что нет:Control.BeginInvoke не работает с TextBox.AppendText, Cross Threading

Рабочих, но не так, как AppendText, если дополнительные меры не будут приняты, который является последним средством:

Public Sub AddMessage2(ByVal newMessage As String) 
    If TextBoxStatus.InvokeRequired Then 
     TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.Text = TextBoxStatus.Text & newMessage & ControlChars.CrLf) 
    Else 
     TextBoxStatus.Text = TextBoxStatus.Text & newMessage & ControlChars.CrLf 
    End If 
End Sub 

То, что я хотел бы использовать, но не работают:

Public Sub AddMessage(ByVal newMessage As String) 
    If TextBoxStatus.InvokeRequired Then 
     TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.AppendText(newMessage)) 
    Else 
     TextBoxStatus.AppendText(newMessage) 
    End If 
End Sub 

Дополнительная информация и обновления: Прежде всего, я приношу свои извинения, что скорее всего не предоставит вам достаточно информации.

По крайней мере часть проблемы, как представляется, инстанцирование формы и вызова AddMessage(newMessage) перед вызовом Show(), так как следующий код работает:

Public Sub AddMessage(ByVal newMessage As String) 
    If Me.Created Then 
     If TextBoxStatus.InvokeRequired Then 
      TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.AppendText(newMessage)) 
     Else 
      TextBoxStatus.AppendText(newMessage) 
     End If 
    End If 
End Sub 

Я всегда могу сделать что-то вроде следующего, но я хотел бы к тому, что происходит :)

Private backLog As String = "" 
Public Sub AddMessage(ByVal newMessage As String) 
    If Me.Created Then 
     If TextBoxStatus.InvokeRequired Then 
      TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.AppendText(backLog & newMessage)) 
     Else 
      TextBoxStatus.AppendText(backLog & newMessage) 
     End If 
     backLog = "" 
    Else 
     backLog &= newMessage 
    End If 
End Sub 

Кроме того, я не считаю, что это очень элегантно ... особенно если добавить ограничения на размер журнала

+0

При нормальных обстоятельствах ваш код должен работать. Вы запускаете вторичный поток, который вызывает «AddMessage» в форме «Sub New» или какой-либо другой точке, так что дескриптор TextBoxStatus еще не создан? Что происходит с вами, добавьте 'If Not TextBoxStatus.IsHandleCreated Then Exit Sub' как 1-й оператор в' AddMessage'? – TnTinMn

+0

@TnTinMn Форма еще не была показана, поэтому я уверен, что вы правы. Я хотел создать форму, не показывая ее, пока пользователь не откроет ее из меню. Я собираюсь посмотреть, как я могу это сделать, но если вы знаете, что у вас на голове, что было бы здорово :) Еще раз спасибо – Jon

+0

Было ли мое предложение выше, чтобы выйти, если дескриптор не создан, разрешает ошибку поперечного потока ? Если это так, я отправляю хак для буфера текста до тех пор, пока не будет создан дескриптор. Однако это будет не так. – TnTinMn

ответ

0

Я бы сказал:

Public Sub AddMessage(ByVal newMessage As String) 
    If TextBoxStatus.InvokeRequired Then 
     TextBoxStatus.BeginInvoke(New Action(Of String)(AddressOf AddMessage), newMessage) 
    Else 
     TextBoxStatus.AppendText(newMessage) 
    End If 
End Sub 
+1

Действительно ли это имеет большое значение? –

+0

У меня была такая же проблема. Я обновил свой пост и спасибо другим за комментарии. – Jon

+0

Я имел в виду, что у ИТ была та же проблема, относящаяся к вышеупомянутому ответу, но спасибо, что нашли время предложить предложение. – Jon