Autres conseils

Travis est correct. l'application Windows Forms sont un seul thread, vous ne pouvez pas accéder à l'interface d'un autre fil. Vous devez marshall l'appel à thread d'interface utilisateur en utilisant BeginInvoke.

Voir: http://msdn.microsoft.com/en-us /library/0b1bf3y3.aspx

Vous devez avoir l'interface utilisateur fil invoquez la méthode de frmMain.refreshStats. Il est-bien sûr plusieurs façons de le faire en utilisant la propriété Control.InvokeRequired et Control.Invoke ( MSDN Documentation ).

Vous pouvez avoir la méthode « EndAsync » faire le thread d'interface d'appel de méthode sûre, ou avoir la méthode refreshStats pour vérifier la sécurité des threads (en utilisant Control.InvokeRequired).

UI EndAsync thread-safe serait quelque chose comme ceci:

Public Delegate Sub Method(Of T1, T2)(ByVal arg1 As T1, ByVal arg2 As T2)

Sub skDataReceived(ByVal result As IAsyncResult)
    Dim frmMain As Form = CType(My.Application.OpenForms.Item("frmMain"), frmMain)
    Dim d As Method(Of Object, Object)
'create a generic delegate pointing to the refreshStats method
    d = New Method(Of Object, Object)(AddressOf frmMain.refreshStats)
'invoke the delegate under the UI thread
    frmMain.Invoke(d, New Object() {d1, d2})
End Sub

Ou vous pouvez avoir la méthode refreshStats vérifier pour voir si elle a besoin de se prévaloir sous le thread d'interface utilisateur:

Public Delegate Sub Method(Of T1, T2)(ByVal arg1 As T1, ByVal arg2 As T2)

Sub refreshStats(ByVal d1 As Object, ByVal d2 As Object)
'check to see if current thread is the UI thread
    If (Me.InvokeRequired = True) Then
        Dim d As Method(Of Object, Object)
'create a delegate pointing to itself
        d = New Method(Of Object, Object)(AddressOf Me.refreshStats)
'then invoke itself under the UI thread
        Me.Invoke(d, New Object() {d1, d2})
    Else
        'actual code that requires UI thread safety goes here
    End If
End Sub

J'ai trouvé la solution (solution, en fait!) À cette erreur de InvalidContextException récurrentes que je suis quand j'interagi ou même lire une propriété d'un formulaire sur le thread d'interface utilisateur.

Je devais sauvegarder et restaurer le contexte d'exécution, avant et après l'interaction avec le thread d'interface utilisateur de ma méthode de rappel Async. Puis l'exception disparaît aussi mystérieusement qu'il est apparu, et vous pouvez lire / propriétés d'écriture, les méthodes d'appel et de faire tout ce que vous voulez avec le fil de l'interface utilisateur, de manière synchrone à partir de votre rappel Async, sans avoir à utiliser des délégués ou lorsqu'il invoque!

Cette exception est en fait un bug au niveau bas dans le .NET se Framewok. Voir rapport Microsoft Connect bug , mais notez que la liste qu'ils pas de solutions fonctionnelles.

Solution: (code de production)

Sub skDataReceived(ByVal result As IAsyncResult)

    // backup the context here
    Dim syncContext As SynchronizationContext = AsyncOperationManager.SynchronizationContext

    // interact with the UI thread
    CType(My.Application.OpenForms.Item("frmMain"), frmMain).refreshStats(d1, d2)

    // restore context.
    AsyncOperationManager.SynchronizationContext = syncContext
End Sub
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top