DOBON.NETプログラミング道掲示板

■35121 / 親記事)  表示動作が重くなる
  
□投稿者/ たこ 一般人(7回)-(2022/08/01(Mon) 01:48:55)
  • アイコン環境/言語:[VB.NET、.NET Framework 4.7.2、VS2019] 
    分類:[.NET] 

    いつもお世話になります。

    ネットの通信状態を表示するフォームを作って表示させていますが、
    フォームの表示/非表示を繰り返すと動作が遅くなってしまいます。

    何が原因で問題が起こっているか解らず、お知恵をお貸しください。

    表示/非表示の部分
    -----------------------------------------------------------
      ''' <summary>
      ''' モニターForm
      ''' </summary>
      Private IOM As IOMonitor

      Private _IOMonitor = False

      ''' <summary>
      ''' IOモニター表示設定
      ''' </summary>
      ''' <returns>True:表示、False:非表示</returns>
      Public Overridable Property IOMonitor As Boolean
        Set(value As Boolean)
          _IOMonitor = value
          If _IOMonitor Then
            IOM = New IOMonitor(Me)
            IOM.Show()
          Else
            IOM.Close()
            IOM = Nothing
          End If
        End Set
        Get
          Return _IOMonitor
        End Get
      End Property
    -------------------------------------------

    メインクラスからモニターFormへはイベントで情報を渡しています。
    -------------------------------------------
    #Region "イベント定義"
      Public Delegate Sub DIODataEventHandler(ByVal sender As Object, ByVal e As NetDataEventArgs)
      ''' <summary>
      ''' ネット接続時のイベント
      ''' </summary>
      Public Event NetOpen As DIODataEventHandler
      ''' <summary>
      ''' ネット切断時のイベント
      ''' </summary>
      Public Event NetClose As DIODataEventHandler
      ''' <summary>
      ''' ネットエラー時のイベント
      ''' </summary>
      Public Event NetError As DIODataEventHandler
      ''' <summary>
      ''' データ送信時のイベント
      ''' </summary>
      Public Event SendData As DIODataEventHandler
    #End Region
    -------------------------------------------


    表示/非表示を繰り返す度に少しずつではありますが、メモリの使用容量が増ますので、
    ガーベージコレクションの問題かなと思い、
    GC.Collectとか入れてみましたが、上手く行きませんでした…

    よろしくお願いします。
マルチポストを報告
違反を報告
引用返信 削除キー/
■35122 / ResNo.1)  Re[1]: 表示動作が重くなる
□投稿者/ Azulean 大御所(532回)-(2022/08/01(Mon) 07:27:41)
  • アイコンNo35121に返信(たこさんの記事)
    > 何が原因で問題が起こっているか解らず、お知恵をお貸しください。
    現時点の情報ではわからないと思います。

    > メインクラスからモニターFormへはイベントで情報を渡しています。
    怪しむとしたらこのあたりでしょうか。

    たとえば、「メインクラスが公開するイベントに、モニターFormのイベントハンドラをAddHandlerしている」状態で、「RemoveHandlerを書いていない」、または「RemoveHandlerが実行されていない」なら、それが原因です。

    当てずっぽうで書くならこのくらいにとどまります。
    これではない場合は、フォームのコードやモニタクラスのコードなどの周辺コードも示しつつ、リークの量の数量イメージがわかる情報を共有してください。(〇〇KB など)
違反を報告
引用返信 削除キー/
■35123 / ResNo.2)  Re[2]: 表示動作が重くなる
□投稿者/ たこ 一般人(8回)-(2022/08/01(Mon) 12:21:35)
  • アイコンNo35122に返信(Azuleanさんの記事)
    > ■No35121に返信(たこさんの記事)

    >>メインクラスからモニターFormへはイベントで情報を渡しています。
    > 怪しむとしたらこのあたりでしょうか。
    >
    > たとえば、「メインクラスが公開するイベントに、モニターFormのイベントハンドラをAddHandlerしている」状態で、「RemoveHandlerを書いていない」、または「RemoveHandlerが実行されていない」なら、それが原因です。

    IOMonitorの初期化処理は次の様になっており、WithEventsでイベントを取得していますが、Addhandler/RemoveHandlerで書いた方が上手く行くのでしょうか?
    ちなみに今はこの様な形になっています。


    IOMonitor(Form)初期化処理
    -------------------------------------------
      Private WithEvents dc As DIO_LC
      Private Delegate Sub MonitorInvoke(sender As Object, e As NetDataEventArgs)


      Friend Sub New(dc As DIO_LC)

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        Me.dc = dc
        DIOName.Text = Strings.Right("000" & Me.dc.Index, 3) & ":" & Me.dc.DIOName & vbCrLf & Me.dc.Place
        Me.Text = Me.dc.Index & ":" & Me.dc.DIOName
      End Sub
    -------------------------------------------

    イベント部処理  複数のスレッドから呼び出される為、Invokeしています。。。
    -------------------------------------------
      Private Sub dc_RecievedData(sender As Object, e As NetDataEventArgs) Handles dc.RecievedData
        If System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(e.Data).Substring(0, 1) = "R" Then
          If Me.InvokeRequired Then
            Me.Invoke(New MonitorInvoke(AddressOf DIO_Disp), sender, e)
            Return
          End If
          DIO_Disp(sender, e)
        End If
      End Sub
    -------------------------------------------

    ちょっと気づきました…

    Private Delegate Sub MonitorInvoke(sender As Object, e As NetDataEventArgs)

    この部分って表示/非表示される度に増えて行く気がします。

    検索したらDelegate.Removeと言うメソッドは見つけました…
    https://docs.microsoft.com/ja-jp/dotnet/api/system.delegate.remove?view=netframework-4.7.2

    …使用例が無く、使い方が全くわかりません^^;
    他にもRemoveAll、RemoveImplなどある様ですが、定義を読んでも解らず…


    どこか良い例が載っているサイトとかあれば教えてください。
違反を報告
引用返信 削除キー/
■35124 / ResNo.3)  Re[3]: 表示動作が重くなる
□投稿者/ たこ 一般人(10回)-(2022/08/01(Mon) 18:46:21)
  • アイコンNo35123に返信(たこさんの記事)
    > ■No35122に返信(Azuleanさんの記事)
    >>■No35121に返信(たこさんの記事)
    >

    > この部分って表示/非表示される度に増えて行く気がします。
    >
    > 検索したらDelegate.Removeと言うメソッドは見つけました…
    > https://docs.microsoft.com/ja-jp/dotnet/api/system.delegate.remove?view=netframework-4.7.2
    >
    > …使用例が無く、使い方が全くわかりません^^;
    > 他にもRemoveAll、RemoveImplなどある様ですが、定義を読んでも解らず…


    解決しました!
    Azulean様のヒントを元にいろいろ試行錯誤し、次の様にしました。
    どうやらdcが邪魔をして遅くなっていた様です。
    念のため、MonitorInvoke.Remove(Nothing, Nothing)も入れました。(使い方合ってるかどうかは自信が無いですが…^^;

    -------------------------------------------
      Private Sub IOMonitor_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
        dc.IOMonitorClose()  '表示/非表示のプロパティがdc側にある為、強制的にFalseにしている
        dc = Nothing
        MonitorInvoke.Remove(Nothing, Nothing)
      End Sub
    -------------------------------------------

    ありがとうございました。
解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -