QA@IT
«回答へ戻る

5599
 安全を期すならば、Formの生存期間とDataTableの生存期間を合わせずに、
 処理に必要なタイミングで毎回生成して、メソッド間は引数などで渡すほうが良いかと思います。
 (生成コストの問題はあるかもしれません)
+
+
+---
+上記コードを試した環境を書き忘れていたので追記
+環境: Windows 10 x64, VS2013, .NET 4.5.1, 32bit 優先

あくまで例えばの話ですが、以下のようなコードの場合に再現させることができます。
閉じる処理が走ったがそのまま続行してしまっているケースです。

' アプリケーションメニューのようなもの
' ボタンを一つ配置する
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fm2 = New Form2()
        fm2.Show()
    End Sub
End Class
' ボタンを一つ配置する
' こちらのボタンをクリックするとエラーが発生する。
Public Class Form2
    Private dt As DataTable
    Public Sub New()
        InitializeComponent()
        dt = New DataTable
        dt.Columns.Add("TAGDAT")
    End Sub

    Private Sub Button1_Click(sender As Object, _
                              e As EventArgs) _
                              Handles Button1.Click
        Dim isError = True
        If isError Then
            ' Error判定で閉じたが、メソッドは抜けない
            Close()
        End If

        Dim dr() As DataRow
        Dim TagDAT = "someDat"
        Try
            dr = dt.Select("TAGDAT = '" & TagDAT & "'")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub

    Private Sub Form2_FormClosed(sender As Object, _
                                 e As FormClosedEventArgs) _
                                 Handles MyBase.FormClosed
        dt = Nothing
    End Sub
End Class

読み取りに時間がかかるためにループの途中でDoEventsでWindowsイベントを優先させてしまっているときに
間違って閉じてしまった(明示的に閉じようとした時なら何か気づくと思いますので)場合なども起こり得ます。

こうなっていると言うわけではありませんが、
Closedでしか解放していなくても起こるケースは存在しますよという参考程度で。

DataSetやDataTableで問題が絶対に起きないとは言えませんので、
Framework側を疑うのであればその日のデータ量が多くなかったかやメモリ使用量を気にしてみるとなにかわかるかもしれません。

1日ぐらいなら起動させたままのシステムはたくさんあると思いますし、
普段問題なく動いているとのことですので、
操作面で変わったことがなかったか、想定していないルートはないか、無理やりでもどうすればClosedを通した後にdt.Selectを通過させることができるのかも考えてみるといいかもしれません。
dt.Selectで例外が起きていたとしても、結果的にそこで例外が発生しただけで実際の原因は別の個所にあるかもしれませんので。
(もう十分に調査はしているのだとは思いますが。)

安全を期すならば、Formの生存期間とDataTableの生存期間を合わせずに、
処理に必要なタイミングで毎回生成して、メソッド間は引数などで渡すほうが良いかと思います。
(生成コストの問題はあるかもしれません)


上記コードを試した環境を書き忘れていたので追記
環境: Windows 10 x64, VS2013, .NET 4.5.1, 32bit 優先

あくまで例えばの話ですが、以下のようなコードの場合に再現させることができます。
閉じる処理が走ったがそのまま続行してしまっているケースです。

```vb
' アプリケーションメニューのようなもの
' ボタンを一つ配置する
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fm2 = New Form2()
        fm2.Show()
    End Sub
End Class
````

```vb
' ボタンを一つ配置する
' こちらのボタンをクリックするとエラーが発生する。
Public Class Form2
    Private dt As DataTable
    Public Sub New()
        InitializeComponent()
        dt = New DataTable
        dt.Columns.Add("TAGDAT")
    End Sub

    Private Sub Button1_Click(sender As Object, _
                              e As EventArgs) _
                              Handles Button1.Click
        Dim isError = True
        If isError Then
            ' Error判定で閉じたが、メソッドは抜けない
            Close()
        End If

        Dim dr() As DataRow
        Dim TagDAT = "someDat"
        Try
            dr = dt.Select("TAGDAT = '" & TagDAT & "'")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub

    Private Sub Form2_FormClosed(sender As Object, _
                                 e As FormClosedEventArgs) _
                                 Handles MyBase.FormClosed
        dt = Nothing
    End Sub
End Class
```

読み取りに時間がかかるためにループの途中でDoEventsでWindowsイベントを優先させてしまっているときに
間違って閉じてしまった(明示的に閉じようとした時なら何か気づくと思いますので)場合なども起こり得ます。

こうなっていると言うわけではありませんが、
Closedでしか解放していなくても起こるケースは存在しますよという参考程度で。

DataSetやDataTableで問題が絶対に起きないとは言えませんので、
Framework側を疑うのであればその日のデータ量が多くなかったかやメモリ使用量を気にしてみるとなにかわかるかもしれません。

1日ぐらいなら起動させたままのシステムはたくさんあると思いますし、
普段問題なく動いているとのことですので、
操作面で変わったことがなかったか、想定していないルートはないか、無理やりでもどうすればClosedを通した後にdt.Selectを通過させることができるのかも考えてみるといいかもしれません。
dt.Selectで例外が起きていたとしても、結果的にそこで例外が発生しただけで実際の原因は別の個所にあるかもしれませんので。
(もう十分に調査はしているのだとは思いますが。)


安全を期すならば、Formの生存期間とDataTableの生存期間を合わせずに、
処理に必要なタイミングで毎回生成して、メソッド間は引数などで渡すほうが良いかと思います。
(生成コストの問題はあるかもしれません)


---
上記コードを試した環境を書き忘れていたので追記
環境: Windows 10 x64, VS2013, .NET 4.5.1, 32bit 優先

回答を投稿

あくまで例えばの話ですが、以下のようなコードの場合に再現させることができます。
閉じる処理が走ったがそのまま続行してしまっているケースです。

' アプリケーションメニューのようなもの
' ボタンを一つ配置する
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fm2 = New Form2()
        fm2.Show()
    End Sub
End Class
' ボタンを一つ配置する
' こちらのボタンをクリックするとエラーが発生する。
Public Class Form2
    Private dt As DataTable
    Public Sub New()
        InitializeComponent()
        dt = New DataTable
        dt.Columns.Add("TAGDAT")
    End Sub

    Private Sub Button1_Click(sender As Object, _
                              e As EventArgs) _
                              Handles Button1.Click
        Dim isError = True
        If isError Then
            ' Error判定で閉じたが、メソッドは抜けない
            Close()
        End If

        Dim dr() As DataRow
        Dim TagDAT = "someDat"
        Try
            dr = dt.Select("TAGDAT = '" & TagDAT & "'")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub

    Private Sub Form2_FormClosed(sender As Object, _
                                 e As FormClosedEventArgs) _
                                 Handles MyBase.FormClosed
        dt = Nothing
    End Sub
End Class

読み取りに時間がかかるためにループの途中でDoEventsでWindowsイベントを優先させてしまっているときに
間違って閉じてしまった(明示的に閉じようとした時なら何か気づくと思いますので)場合なども起こり得ます。

こうなっていると言うわけではありませんが、
Closedでしか解放していなくても起こるケースは存在しますよという参考程度で。

DataSetやDataTableで問題が絶対に起きないとは言えませんので、
Framework側を疑うのであればその日のデータ量が多くなかったかやメモリ使用量を気にしてみるとなにかわかるかもしれません。

1日ぐらいなら起動させたままのシステムはたくさんあると思いますし、
普段問題なく動いているとのことですので、
操作面で変わったことがなかったか、想定していないルートはないか、無理やりでもどうすればClosedを通した後にdt.Selectを通過させることができるのかも考えてみるといいかもしれません。
dt.Selectで例外が起きていたとしても、結果的にそこで例外が発生しただけで実際の原因は別の個所にあるかもしれませんので。
(もう十分に調査はしているのだとは思いますが。)

安全を期すならば、Formの生存期間とDataTableの生存期間を合わせずに、
処理に必要なタイミングで毎回生成して、メソッド間は引数などで渡すほうが良いかと思います。
(生成コストの問題はあるかもしれません)

あくまで例えばの話ですが、以下のようなコードの場合に再現させることができます。
閉じる処理が走ったがそのまま続行してしまっているケースです。

```vb
' アプリケーションメニューのようなもの
' ボタンを一つ配置する
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fm2 = New Form2()
        fm2.Show()
    End Sub
End Class
````

```vb
' ボタンを一つ配置する
' こちらのボタンをクリックするとエラーが発生する。
Public Class Form2
    Private dt As DataTable
    Public Sub New()
        InitializeComponent()
        dt = New DataTable
        dt.Columns.Add("TAGDAT")
    End Sub

    Private Sub Button1_Click(sender As Object, _
                              e As EventArgs) _
                              Handles Button1.Click
        Dim isError = True
        If isError Then
            ' Error判定で閉じたが、メソッドは抜けない
            Close()
        End If

        Dim dr() As DataRow
        Dim TagDAT = "someDat"
        Try
            dr = dt.Select("TAGDAT = '" & TagDAT & "'")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub

    Private Sub Form2_FormClosed(sender As Object, _
                                 e As FormClosedEventArgs) _
                                 Handles MyBase.FormClosed
        dt = Nothing
    End Sub
End Class
```

読み取りに時間がかかるためにループの途中でDoEventsでWindowsイベントを優先させてしまっているときに
間違って閉じてしまった(明示的に閉じようとした時なら何か気づくと思いますので)場合なども起こり得ます。

こうなっていると言うわけではありませんが、
Closedでしか解放していなくても起こるケースは存在しますよという参考程度で。

DataSetやDataTableで問題が絶対に起きないとは言えませんので、
Framework側を疑うのであればその日のデータ量が多くなかったかやメモリ使用量を気にしてみるとなにかわかるかもしれません。

1日ぐらいなら起動させたままのシステムはたくさんあると思いますし、
普段問題なく動いているとのことですので、
操作面で変わったことがなかったか、想定していないルートはないか、無理やりでもどうすればClosedを通した後にdt.Selectを通過させることができるのかも考えてみるといいかもしれません。
dt.Selectで例外が起きていたとしても、結果的にそこで例外が発生しただけで実際の原因は別の個所にあるかもしれませんので。
(もう十分に調査はしているのだとは思いますが。)


安全を期すならば、Formの生存期間とDataTableの生存期間を合わせずに、
処理に必要なタイミングで毎回生成して、メソッド間は引数などで渡すほうが良いかと思います。
(生成コストの問題はあるかもしれません)