こんにちは、初心者です。
Visual Studio 2008 Version 9.0.30729.1 SP OS:Vista Home Premium SP2 で勉強中です。
http://msdn.microsoft.com/ja-jp/events/dd229369.aspx
ステップ 7 ハンズオン : 非同期処理を使ったパフォーマンスの向上のサンプルプログラムでエラーが発生しました。
マイクロソフトに直に問い合わせる方法が見つからなかったので、このフォーラムに質問させて頂きます。
エラー内容:非同期処理を選択して開始ボタンを押すと
Private Sub additem(ByVal strItem As String)
Me.ListBox1.Items.Add(strItem)
End Sub
で、「有効でないスレッド間の操作:コントロールが作成されたスレッド以外のスレッドからコントロール'ListBox1'がアクセスされました。」というエラーが発生しました。
Step6の章の最後に以下の説明がありました。
さて、ここで大事な点があります。BeginInvoke で非同期処理を実行して処理が完了したら必ず、EndInvoke を実行しなければならないという事です。EndInvoke を実行しないとメモリーリークが発生する可能性がありますので、忘れずに実装しましょう。EndInvoke を実行するためのオブジェクトは完了通知のためのメソッドに渡されるオブジェクトから取り出すことができます。引数で渡されたオブジェクトをキャストし て、EndInvoke を実行しましょう。
これが原因なのかと思い、フォーラムで検索したところ、
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/f2cbd0d8-b0e3-407d-9a3c-fb5a593b8b8e
タイトル:Control.EndInvoke は呼ばなくてもよい?
を読ませて頂きました所、今回のエラーの原因にはならないのではと推測しました。
なにぶん、初心者なのでエラー内容から原因を特定できなくて困っています。
このサンプルプログラムを完成するためのご支援をお願いします。
(もし、EndInvokeを追記するにしても、前述の説明だけでコード化する知識もありません。)
よろしくお願いします。
以下にコードを添付します。
Public Class Form1
Private Sub myProc()
Dim i As Integer
For i = 1 To 5
' 以下のコードを追加
If Me.optDoEvents.Checked Then
Application.DoEvents()
End If
' ここまで
System.Threading.Thread.Sleep(500)
Me.additem(i.ToString() & "回目の処理完了 " & Now.ToLongTimeString())
Next
End Sub
Private Sub additem(ByVal strItem As String)
Me.ListBox1.Items.Add(strItem)
End Sub
Private Delegate Sub mydelegate()
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim dlgMyProc As New mydelegate(AddressOf myProc)
Me.ListBox1.Items.Clear()
Me.additem("start")
If Me.optDelegate.Checked Then
dlgMyProc.BeginInvoke(AddressOf comp, dlgMyProc)
Else
Me.myProc()
Me.additem("end")
End If
End Sub
Private Sub comp(ByVal a As IAsyncResult)
Additem("end")
End Sub
End Class