2009-08-25 30 views
2

私はサイトを見渡しましたが、この件に関する私が見つけた質問は、C#(私が開発したアプリケーションはVB.NETで書かれています)ですので、 1。セーブ機能がうまく動作しますが、ときに私は、クロススレッドのエラーを取得するクロススレッド操作が有効ではありませんVB.NET

Private Sub SaveData() 
    SaveData(LoadedFilePath) 
End Sub 
Private Sub SaveData(ByVal filepath As String) 
    If InvokeRequired Then 
     Me.Invoke(New MethodInvoker(AddressOf SaveData)) 
    End If 
    Try 
     Me.Cursor = Cursors.WaitCursor 
     Dim oSettings As New SettingsClass(filepath) 
     Dim oEnc As New AES 
     With oSettings 
      //' Code removed for brevity 
     End With 
     oEnc = Nothing 
     oSettings.SaveSettings() 
     savedLbl.Visible = True 
     If SavedTimeout IsNot Nothing Then 
      Try 
       SavedTimeout.StopEvent() 
      Catch 
      End Try 
     End If 
     SavedTimeout = New TimedEvent(Now.AddSeconds(5)) 
     SavedTimeout.StartEvent() 
     Me.Cursor = Cursors.Default 
    Catch ex As Exception 
     MsgBox(ex.Message) 
    End Try 
End Sub 

Private Sub saveBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles saveBtn.Click 
    If Not LoadedFilePath = String.Empty Then 
     Dim oTrd = New Threading.Thread(AddressOf SaveData) 
     oTrd.Start() 
    End If 
End Sub 

そして、ここでは、メソッドです:私は私のスレッドを呼び出していますのはここ

ですプログラムはカーソルをデフォルトに戻そうとします。この問題を解決するにはどうすればよいですか?

答えて

5

オーナー(GUI)スレッドでメソッドを呼び出す方法が間違っています。呼び出しが必要な場合は、メソッドの残りのコードを実行しないでください。そうすると、GUIスレッドとバックグラウンドスレッドの両方で実行され、バックグラウンドスレッドからGUI要素にアクセスしようとすると、クロススレッドエラーが発生します。

呼び出しは次のようになります。

Private Sub SaveData(ByVal filepath As String) 
    If InvokeRequired Then 
     Me.Invoke(New MethodInvoker(AddressOf SaveData)) 
    Else 
     ... the actual code 
    End If 
End Sub 

しかし、それはとにかくGUIスレッドで自分自身を呼び出すために持っていたときに、なぜあなたは、バックグラウンドスレッドでメソッドを起動していますか?

+0

私は他のものを忘れて信じられません...日の終わりFTL!ソリューションに感謝します:) – Anders

+0

@アンダーソン:個人的に私は 'Else'なしでそれを残して、' Me.Invoke() 'の直後に' Return'を追加して、メソッドがそれ以上実行されないようにします。ネスティングを減らしてコードを読みやすくするのに役立ちます。 – STW

+0

@yoooder:チップをありがとう、私はこれを念頭に置いておきます。 – Anders

1

ユーザーインターフェイスへの呼び出しが許可されていないヘルパースレッドを開始しました。 UIスレッド自体からのカーソルの設定のみが許可されています。

これを達成するには、ヘルパースレッドからイベントを起動する必要があります。これは、UIスレッドに作業完了を通知し、カーソルを戻すか、UIスレッドへの呼び出しで行います。

private void ResetCursor() 
{ 
    this.Cursor = Cursor.Default; 
} 

private delegate void UpdateCursor(); 
private void SaveData() 
{ 
    //Do your work here 
    if(this.InvokeRequired) 
    { 
     this.Invoke(new UpdateCursor(ResetCursor)); 
    } 
    else 
    { 
     ResetCursor(); 
    } 
} 
0

マルチスレッドWindowsフォームアプリケーションでは、作成したスレッド以外のスレッドからコントロールのメソッドまたはプロパティを呼び出すことはできません。すべてのクロススレッド呼び出しは、Control.InvokeまたはControl.BeginInvokeメソッドを使用して、コントロールを作成したスレッド(通常はメインスレッド)に明示的にマーシャリングする必要があります。ここで

は、あなたがこの問題を解決するお手伝いをするために使用できるWebページです:

http://www.dreamincode.net/forums/showtopic35616.htm C#

http://www.codeproject.com/KB/vb/ISinchronizedInvoke.aspx VB.NET

関連する問題