DOBON.NETプログラミング道掲示板
(現在 過去ログ1 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■32906 / inTopicNo.1)  AddHandlerをループすると思い通りの結果が返ってこない...
  
□投稿者/ こたろう 一般人(1回)-(2015/04/09(Thu) 10:59:42)
  • アイコン環境/言語:[Win7 VB.NET] 
    分類:[.NET] 

    超初心者ですが、よろしくお願いいたします。

    vb.netでAddHandlerを繰り返し処理の中で実行すると、思い通りの結果が得られません。
    やりたいことは、ある画像処理が終わった時にその画像のある値を順番に変数に落としていきたいのです。
    しかし、結果は「1・2・3・4・・・」となってほしいのに「3・4・1・2・・・」となったり、「1・3・2・4・・・」となったり、その時々によって結果がバラバラに返ってきます。
    簡単に処理内容を記載しますので、どこがいけないのか教えていただけると助かります。
    ちなみに、仕様の変更により1件のみを処理する記述だったのを繰り返し処理するように直したのですが、このような結果になってしまっています。


    Private wk(9) as integer
    Private wkSUM as integer


    Private Sub Syori()
    wkSUM =0

    For i As Integer = 1 to 10
    AddHandler 画像処理終了時のイベント AddressOf EndSyori(i)
    Next
    End Sub


    Private Sub EndSyori(i as integer)
     wk(i) = 画像のある値(i)
    wkSUM += 画像のある値(i)

    Me.Invoke(New MethodInvoker(AddressOf disp_set))
    End Sub


    Private Sub disp_set()
     labelwk.Text = wkSUM
    End Sub


    どうぞよろしくお願いいたします。

引用返信 削除キー/
■32907 / inTopicNo.2)  Re[1]: AddHandlerをループすると思い通りの結果が返ってこない...
□投稿者/ 魔界の仮面弁士 大御所(953回)-(2015/04/09(Thu) 11:15:01)
  • アイコンNo32906に返信(こたろうさんの記事)
    > vb.netでAddHandlerを繰り返し処理の中で実行すると、思い通りの結果が得られません。
    「AddHandler を繰り返し実行」している理由が読み取れませんでした。


    Public Class Form1
     'こちらは Handles 句付きのイベントハンドラーです
     Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
      'その中で、Button2 の Click イベントを AddHandler します
      AddHandler Me.Button2.Click, AddressOf Me.Button2_Click
     End Sub

     'こちらは Handles 句無しにしています
     Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs)
      MsgBox("Button2")
     End Sub
    End Class


    たとえば上記では、AddHandler が複数回登録できるようにしていますが、
    それが必要になる場面というのが思い当たりませんでした。


    > やりたいことは、ある画像処理が終わった時にその画像のある値を順番に変数に落としていきたいのです。
    > しかし、結果は「1・2・3・4・・・」となってほしいのに「3・4・1・2・・・」となったり、
    > 「1・3・2・4・・・」となったり、その時々によって結果がバラバラに返ってきます。

    1 つの「ある画像処理のオブジェクト」が、終了イベントを複数回発生させるのでしょうか。
    それとも、複数個の「ある画像処理のオブジェクト」がそれぞれ、終了イベントを発生させるのでしょうか。

    前者であれば、WithEvents で十分でしょうし、そもそも AddHandler を複数回使う理由が思い当たりません。
    イベント通知がされるたびに、RemoveHandler で解除していくなら、複数回の AddHandler もアリですが…。

    後者の場合は、それぞれのオブジェクトごとに AddHandler する必要があるでしょうけれども、
    イベントの発生順がどうなるかは実装依存です。ただ、イベントの第一引数(sender)に、
    イベント発生元となった「画像処理のオブジェクト」が格納されているわけですから、
    それを使えば、何番目のオブジェクトの完了通知であるのかを判断できるはずです。
引用返信 削除キー/
■32908 / inTopicNo.3)  Re[2]: AddHandlerをループすると思い通りの結果が返ってこない...
□投稿者/ こたろう 一般人(2回)-(2015/04/09(Thu) 13:29:41)
  • アイコン魔界の仮面弁士さん、ありがとうございます。

    > 1 つの「ある画像処理のオブジェクト」が、終了イベントを複数回発生させるのでしょうか。
    > それとも、複数個の「ある画像処理のオブジェクト」がそれぞれ、終了イベントを発生させるのでしょうか。

    説明が下手で申し訳ありませんでしたが、やりたいことは後者の場合になります。

    > 後者の場合は、それぞれのオブジェクトごとに AddHandler する必要があるでしょうけれども、
    > イベントの発生順がどうなるかは実装依存です。ただ、イベントの第一引数(sender)に、
    > イベント発生元となった「画像処理のオブジェクト」が格納されているわけですから、
    > それを使えば、何番目のオブジェクトの完了通知であるのかを判断できるはずです。

    やはり発生順はこちらの思うように(1から10へ順番通り)はいかないのですね。
    しかし、イベントの引数で判断できるということですので、それを頼りにこちらの思うような順番で変数に格納出来るように頑張ってみます。

    また分からないことが出てきましたら質問させていただきたいと思いますが、的確なアドバイスをありがとうございました。
    まだ解決済みにはしませんので、よろしくお願いいたします。
引用返信 削除キー/
■32909 / inTopicNo.4)  Re[3]: AddHandlerをループすると思い通りの結果が返ってこない...
□投稿者/ 魔界の仮面弁士 大御所(954回)-(2015/04/09(Thu) 15:09:16)
  • アイコンNo32908に返信(こたろうさんの記事)
    > やはり発生順はこちらの思うように(1から10へ順番通り)はいかないのですね。
    今回は、「画像処理オブジェクト」が 10 個あるのですよね?

    「1 の処理が終わったら、次に 2 の処理を始める」という処理手順になっているなら、
    終了通知のイベントは、1 から 10 まで順に発生するはずです。

    しかし、「1〜10 が同時に並列実行され、終わった処理から順次通達される」場合、
    終了イベントの発生順は不定になります。

    ゆえに
    >> イベントの発生順がどうなるかは実装依存です。
    ということです。


    > しかし、イベントの引数で判断できるということですので、
    > それを頼りにこちらの思うような順番で変数に格納出来るように頑張ってみます。

    10 個のオブジェクトに、それぞれ別々のイベントハンドラを割り当てているなら、

     Private Results(9) As 処理結果クラス
     Private Sub Completed0(sender As Object, e As HogeEventArgs)
      Results(0) = e.処理結果
     End Sub
     Private Sub Completed1(sender As Object, e As HogeEventArgs)
      Results(1) = e.処理結果
     End Sub
     Private Sub Completed9(sender As Object, e As HogeEventArgs)
      Results(9) = e.処理結果
     End Sub

    のようなイメージで拾えるでしょうし、10 個のオブジェクトそれぞれが、
    1 つのイベントハンドラを共有しているなら、

     Private proc(9) As 画像処理クラス
     Private Results(9) As 処理結果クラス
     Private Sub Form1_Load(…
      proc(0) = New 画像処理クラス(…)
      proc(1) = New 画像処理クラス(…)
      proc(9) = New 画像処理クラス(…)
      Array.ForEach(proc, Sub(p) AddHandler p.Completed, AddressOf Me.Completed)
     End Sub
     Private Sub Completed(sender As Object, e As HogeEventArgs)
      Dim index As Integer = Array.IndexOf(proc, sender)
      Results(index) = e.処理結果
     End Sub

    のように、引数 sender からイベントの通知元を特定できるでしょう。
引用返信 削除キー/
■32910 / inTopicNo.5)  Re[4]: AddHandlerをループすると思い通りの結果が返ってこない...
□投稿者/ こたろう 一般人(3回)-(2015/04/09(Thu) 17:09:11)
  • アイコンNo32909に返信(魔界の仮面弁士さんの記事)

    > のようなイメージで拾えるでしょうし、10 個のオブジェクトそれぞれが、
    > 1 つのイベントハンドラを共有しているなら、

    > のように、引数 sender からイベントの通知元を特定できるでしょう。

    この箇所の内容でうまく処理することが出来ました。
    本当にありがとうございました。

引用返信 削除キー/
■32911 / inTopicNo.6)  Re[5]: AddHandlerをループすると思い通りの結果が返ってこない...
□投稿者/ こたろう 一般人(4回)-(2015/04/09(Thu) 17:10:32)
  • アイコン解決済みにするのを忘れました、すみません。
解決み!
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -