マルチスレッド-非同期デリゲート-AsyncCallback-Debug.Print について

解決


まさお  2013-05-21 22:56:36  No: 148152

まさお と申します。  宜しくお願い致します。

  WinXP Pro SP3,VB2010 Express SP1 です。

  vb.netに関わるあるWebページ http://codezine.jp/article/detail/139?p=2
  「非同期デリゲート」-「コールバックメソッドの使用」を参考に下記を作成しました。

  下記において、Debug.Print に関して教えてください。

  コンソールアプリケーションにすると Dos窓,又は イミディエイトウィンドウに 「1:」〜「8:」の全てが表示されます。
  しかし、フォームアプリケーションにすると「2:, 4:, 6:, 8:」はConsole.WriteLineですから何も表示されないのは当然としても、
Debug.Printの「1:, 3:」は表示されますが「5:, 7:」がイミウィンドに表示されません。
  原因は何でしょうか?

以上、宜しくお願い致します。

Class Class1
    Delegate Function WriteStringAsyncDelegate(ByVal sleepTime As Integer) As Integer
    'エントリポイント
        Public Shared Sub Main()
            Dim dlgt As New WriteStringAsyncDelegate(AddressOf WriteString)
            Dim ar As IAsyncResult = dlgt.BeginInvoke(1000, New AsyncCallback(AddressOf CallbackMethod), dlgt)
            Debug.Print("1:" & "Start")
            Console.WriteLine("2:" & "Start")
            Console.ReadLine()
        End Sub
    '非同期で呼び出すメソッド
        Private Shared Function WriteString(ByVal sleepTime As Integer) As Integer
            Debug.Print("3:" & Now.ToLongTimeString)
            Console.WriteLine("4:" & Now.ToLongTimeString)
            System.Threading.Thread.Sleep(sleepTime)
            Debug.Print("5:" & Now.ToLongTimeString)
            Console.WriteLine("6:" & Now.ToLongTimeString)
            Return 0
        End Function
    'コールバックメソッド
        Private Shared Sub CallbackMethod(ByVal ar As IAsyncResult)
            Dim dlgt As WriteStringAsyncDelegate = CType(ar.AsyncState, WriteStringAsyncDelegate)
            Dim ret As Integer = dlgt.EndInvoke(ar)
            Debug.Print("7:結果:{0}", ret)
            Console.WriteLine("8:結果:{0}", ret)
        End Sub
End Class


YuO  2013-05-22 06:25:11  No: 148153

単に,Sleep中にプログラムの実行が終わった,ということはありませんか。
Console ApplicationではConsole.ReadLine()で待っていたけれども,
Windows Forms Applicationでは待つことがなくなったため,そのまま終了しているのではないでしょうか。

ちなみに,System.Func(Of T, TResult)という汎用のデリゲートを使えばデリゲートの定義は不要ですし,
.NET 4からはSystem.Threading.Tasks.Taskを使った方がよいかもしれません。
# Taskのとる引数が,Func(Of Object, TResult)なのが残念なところ。


まさお  2013-05-22 18:09:09  No: 148154

YuOさん、ありがとうございました。

> 単に,Sleep中にプログラムの実行が終わった,ということはありませんか。
  おっしゃる通りでした。
  ご指摘を受け、ハタと気がつきました。

> Console ApplicationではConsole.ReadLine()で待っていたけれども,
  Console.ReadLine()の次行にMsgBox("")を追記して待機させたところ「5:, 7:」がイミウィンドに表示されました。

  別スレッド実行中にメイン部分が終了すればプログラム自体が終了する、という言われてみれば当たり前の事が
直感的に判らないようではダメですネ。

> ちなみに,System.Func(Of T, TResult)という汎用のデリゲートを使えばデリゲートの定義は不要ですし,
> .NET 4からはSystem.Threading.Tasks.Taskを使った方がよいかもしれません。
  アドバイスありがとうございます。
  今、マルチスレッド,デリゲートを勉強中で、今回質問したような内容にある程度習熟したらアドバイス内容にも挑戦いたします。

  ありがとうございました。
  解決しました。
  暫くしたら閉じます。


まさお  2013-05-23 18:13:43  No: 148155

閉じます。
YuOさん、ありがとうございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加