2017-09-21 9 views
-2

私はオンラインで検索していますが、私のエラーのために適切な修正を見つけることができません:Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.クロススレッドの問題?

私は私のサイズの変更をどのように呼び出すのですか?いくつかの時間を動作し、他は上記のコードをスロー

私のコードは次のとおりです。

'Handler to handle screen resizes! (Tablet being flipped etc...) 
Private Sub TouchRadio_Resize(sender As Object, e As EventArgs) Handles Me.Resize 
    Dim thread As New Thread(AddressOf resizescreen) 
    thread.Start() 
End Sub 

Public Sub resizescreen() 
    System.Threading.Thread.Sleep(1) 
    For index As Integer = 1 To 50000 
     If Screen.PrimaryScreen.Bounds.Width = (Screen.PrimaryScreen.Bounds.Width + 17) Then 
      Exit For 
     End If 
     Dim screenWidth As Integer = Screen.PrimaryScreen.Bounds.Width 
     screenWidth = (screenWidth + 17) 
     Dim screenHeight As Integer = Screen.PrimaryScreen.Bounds.Height 
     Me.Size = New System.Drawing.Size(screenWidth, screenHeight) 'Here it errors at 
     GeckoWebBrowser1.Size = New System.Drawing.Size(screenWidth, screenHeight) 
     Me.Location = New Point(0, 0) 
    Next 
End Sub 
+0

この方法では、複雑さと冗長性が大幅に低下する可能性があります。 'Me.Location = New Point(0、0)'を50k回呼び出さなければならないのですか? If Screen.PrimaryScreen.Bounds.Width =(Screen.PrimaryScreen.Bounds.Width + 17) 'を等価から> = – djv

答えて

1

あなたはこの小さなヘルパーを使用することができます。

Public Shared Sub InvokeIfRequired(c As Control, action As Action(Of Control)) 
    If c.InvokeRequired Then 
     c.Invoke(New Action(Sub() action(c))) 
    Else 
     action(c) 
    End If 
End Sub 

し、その中に自分のものを置く:

InvokeIfRequired(Me.Size, 
     Sub() 
      For index As Integer = 1 To 50000 
       If Screen.PrimaryScreen.Bounds.Width = (Screen.PrimaryScreen.Bounds.Width + 17) Then 
        Exit For 
       End If 
       Dim screenWidth As Integer = Screen.PrimaryScreen.Bounds.Width 
       screenWidth = (screenWidth + 17) 
       Dim screenHeight As Integer = Screen.PrimaryScreen.Bounds.Height 
       Me.Size = New System.Drawing.Size(screenWidth, screenHeight) 'Here it errors at 
       GeckoWebBrowser1.Size = New System.Drawing.Size(screenWidth, screenHeight) 
       Me.Location = New Point(0, 0) 
      Next 
     End Sub) 

この方法は、必要であれば、それが呼び出されます。


UPDATE

私はいくつかのコメントは非常に有用であることを、指摘したいと思います。 @djvはすばらしい拡張子を説明しており、@Visual Vincentが指摘しているように、できるだけ呼び出す必要はありません。

+1

に変更します。' InvokeIfRequired'でループ全体をラップすると、マルチスレッドの目的を完全に無効にします。 UIに実際にアクセスする行 - また、呼び出されたメソッド内で呼び出し側コントロールを取得する予定がない限り、 'Action(Of Control)'を使用することには意味がありません。通常の 'Action'を使うだけで十分です。 –

+1

このメソッドは次のように書かれています: ' Public Sub InvokeIfRequired(コントロールとしてのコントロール、MethodInvokerのアクション)' 'If control.InvokeRequired then control.Invoke(アクション)Else action()' 'End Sub' – djv

+0

あなたは一部です正しい。呼び出し自体はコストがかかります。したがって、Loopが50000を呼び出した場合、それはさらに遅くなり、大きな呼び出しが発生します。しかし、一般的にあなたは正しいです。小さな呼び出しを行います。 – Marius

関連する問題