2012-03-16 12 views
0
いるContextMenuStrip

私は「スレッド」との問題を抱えています。別のプロセスで動作する2つの 'フォーム'が必要です。たとえば、あるフォームから 'OpenFileDialog'を開き、別のフォームが別に動作し、その他いくつかのことをします。 (私は私の悪い記述のためのサリーよ、私のコードを参照してください。)クロススレッド操作ではない有効:

私は「スレッド」を使用し、それが仕事の罰金です。私の 'フォーム'に 'ContextMenuStrip'コントロールがある場合、 'クロススレッド操作が有効ではありません'というエラーが発生しました。 私を助けてください。

ありがとうございました。

============================================== =================================== FormMain:

Public Class FormMain 

Private Sub cmdShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdShow.Click 
    Form2.ShowMe() 
End Sub 

End Class 

===== ========================================== ========================== のForm2:

Public Class Form2 

'Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components) 
'Me.Panel1 = New System.Windows.Forms.Panel 
'Me.Panel1.ContextMenuStrip = Me.ContextMenuStrip1 


Public Shared Thread_2 As System.Threading.Thread 
Public MyDefaultWindowState = FormWindowState.Normal 

Private Delegate Sub dlgShowMe() 
Public Sub ShowMe() 
    If Thread_2 IsNot Nothing AndAlso Thread_2.ThreadState = Threading.ThreadState.Running Then 
     If Me.InvokeRequired Then 
      Dim d As New dlgShowMe(AddressOf Me.ShowMe) 
      Me.Invoke(d) 
     Else 
      Show_Activate_() 
     End If 
    Else 
     Thread_2 = New System.Threading.Thread(AddressOf Me.Show_View_) 
     Thread_2.SetApartmentState(System.Threading.ApartmentState.STA) 
     Thread_2.IsBackground = False 
     Thread_2.Start() 
    End If 
End Sub 

Private Sub Show_Activate_() 
    Try 
     Me.Enabled = True 
     Me.ShowInTaskbar = True 
     Me.WindowState = Me.MyDefaultWindowState 

     Me.BringToFront() 
     Me.Activate() 
    Catch ex As Exception 
     MsgBox(ex.Message, , "Show_Activate_") 
    End Try 
End Sub 
Private Delegate Sub dlgShow_View_() 
Private Sub Show_View_() 
    Me.Enabled = True 
    Me.ShowInTaskbar = True 

    Try 
     Me.ShowDialog() 
    Catch ex As Exception 
     MsgBox(ex.Message, MsgBoxStyle.Critical,"Show_View_") 
    End Try 
End Sub 


Private Sub cmdOpenFileDialog1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOpenFileDialog1.Click 
    OpenFileDialog1.ShowDialog() 
End Sub 

End Class 

============== ==================================ここ

は、私のソースコードです: http://www.mediafire.com/?m8e8i51rr51a35i [63キロバイト]

ファイル名を指定して実行 'FormMain'。 'cmdShow'をクリックします。 'Form2'と表示された場合は となります。 'Panel1'を右クリックします。 'ContextMenuStrip1'が表示されます。

閉じる 'Form2。

[cmdShow]を再度クリックします。 'Form2'と表示された場合は となります。もう一度 'Panel1'を右クリックします。 しかし、あなたはエラーを見ることができます...

+0

。 – Steve

+0

同じですが、何が間違っているか把握するためのコードをダウンロードしていません。 – squelos

答えて

0

UIスレッド(メインスレッド)以外のスレッドからGUIを変更しようとしているためです。

UIを更新する前、またはUIに関連する操作を行う前に、任意のコントロールで呼び出す必要があります。

は、以下のコードを検討:

Friend Shared Sub RaiseUiEvent(ByVal hnd As EventHandler, ByVal sender As Object, ByVal e As EventArgs) 
    Dim uiRef = GlobalManager.GetInstance().UI 'uiRef is just a ref to a control of my UI 

    uiRef.BeginInvoke(hnd, sender, e)  
End Sub 

BeginInvokeは非同期であり、Invokeは、同期である

のparamsは、次のとおり実行されるデリゲート、最終的に渡されるオブジェクトの配列。

しかし、私は何か気になるのですが、2つのフォームを別々のスレッドで「機能する」ようにしたいのはなぜですか?いずれにしても、あなたのGUIに重い処理はすべきではありません。

編集:

OKので、私は間違っているのか理解:あなたは、単に非モーダルダイアログボックスが欲しいです! OpenFileDialogはモーダルです(C# OpenFileDialog Non-Modal possible) 問題はスレッドとは関係ありません!

+0

あなたは何を言っているのか理解していません。もっと説明できますか?可能であれば、私のソースコードをチェックして欲しい。ありがとう。 –

+0

スレッドの問題が発生しています。基本的には、UIを変更できないスレッドがUIを変更しようとしています。そのため、例外が発生します。 – squelos

+0

スレッドがUIを変更できるようにする方法。 –

0

あなたはそれを変更する必要があり、この部分に

Private Delegate Sub dlgShow_View_() 
Private Sub Show_View_() 
    Me.Enabled = True 
    Me.ShowInTaskbar = True 

    Try 
     Me.ShowDialog() 
    Catch ex As Exception 
     MsgBox(ex.Message, MsgBoxStyle.Critical,"Show_View_") 
    End Try 
End Sub 

を起動していない:あなたはunknow外部リンクをクリックして行くために私たちを強制的にここに関連するコードを投稿してはならない

Private Delegate Sub dlgShow_View_() 
Private Sub Show_View_() 
    if Me.InvokeRequired Then 
     Dim d as New dlgShow_View_(adressOf Show_View_) 
    else 
    Me.Enabled = True 
    Me.ShowInTaskbar = True 

    Try 
     Me.ShowDialog() 
    Catch ex As Exception 
     MsgBox(ex.Message, MsgBoxStyle.Critical,"Show_View_") 
    End Try 
    End If 
End Sub 
+0

私は 'ContextMenuStrip1.InvokeRequired = true'ではなく 'ContextMenuStrip1.Invoke(d)'を使用すると、このコードが機能しないので、これはうまくいきません! –

関連する問題