Мне нелегко пытаться понять, что кажется случайным броском cross-thread exceptions
.Когда ожидать «перекрестного потока»?
Примеры
При вызове в другом потоке, почему это работает:
Dim text As String = Me.Text
В то время как это будет сгенерировано исключение:
Me.Text = "str"
Что делает его еще более странным является что следующие do работают:
Dim text As String = Me.ctl.Margin.ToString() : Me.ctl.Margin = New Padding(1, 2, 3, 4)
Dim text As String = Me.ctl.MyProp : Me.MyProp = "str"
Примечание
Да, я знаю, что я мог бы просто вызвать свойство как это:
Me.Invoke(Sub() Me.Text = "str")
Вопрос
Так что, когда я могу ожидать cross-thread exception
?
Код
Это код, который я использовал для тестирования Me.Text
свойства:
Public Class Form1
Public Sub New()
Me.InitializeComponent()
Me.ctl = New Control()
Me.ctl.Text = "test_control"
Me.Controls.Add(Me.ctl)
End Sub
Private Sub TestGet(sender As Object, e As EventArgs) Handles Button1.Click
Dim t As New Thread(AddressOf Me._Proc)
t.Start(TESTTYPE.GET)
End Sub
Private Sub TestSet(sender As Object, e As EventArgs) Handles Button2.Click
Dim t As New Thread(AddressOf Me._Proc)
t.Start(TESTTYPE.SET)
End Sub
Private Sub _Proc(tt As TESTTYPE)
Dim text As String = String.Empty
Dim [error] As Exception = Nothing
Try
If (tt = TESTTYPE.GET) Then
text = Me.ctl.Text
ElseIf (tt = TESTTYPE.SET) Then
Me.ctl.Text = "test"
End If
Catch ex As Exception
[error] = ex
End Try
Me.Invoke(Sub() Me._Completed(tt, text, [error]))
End Sub
Private Sub _Completed(tt As TESTTYPE, text As String, ByVal [error] As Exception)
If ([error] Is Nothing) Then
If (tt = TESTTYPE.GET) Then
MessageBox.Show(String.Concat("Success: '", text, "'"), tt.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Information)
ElseIf (tt = TESTTYPE.SET) Then
MessageBox.Show("Success", tt.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Else
MessageBox.Show([error].Message, tt.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
Private ReadOnly ctl As Control
Private Enum TESTTYPE
[GET] = 0
[SET] = 1
End Enum
End Class
Редактировать
Это не бросить исключение:
Public Event TestChanged As EventHandler
Public Property Test() As String
Get
Return Me.m_test
End Get
Set(value As String)
If (value <> Me.m_test) Then
Me.m_test = value
Me.Invalidate()
RaiseEvent TestChanged(Me, EventArgs.Empty)
End If
End Set
End Property
Что вы подразумеваете под «правами на доступ»? Как вы можете видеть в примере, я _can_ обращаюсь к методу 'get_Text' элемента управления, но' set_Text' выдает исключение. –
«права на доступ» означает, что если я пытаюсь получить доступ к 'функции' или' property' для элемента управления, из 'thread', который не имеет права его вызывать ....... – dbw
Вы имеете в виду [доступ уровни] (http://msdn.microsoft.com/en-us/library/76453kax.aspx)? Если да, это довольно очевидно. Если нет, то как я могу узнать, могу ли я/не получить доступ к getter/setter свойства. Где определяются права доступа? –