0

button.click サブに次のコードがあります。1 つのアクセス DB からデータを取得し、行を 1 つずつ SQL DB にロードします。コードを挿入する行は、既にテスト済みであるためコメント化されています。

Dim cSQL As New SqlConnection(conSQL)
    Dim fecha1, fecha2 As Date
    Dim strfecha1, strfecha2 As String
    For Each dr As DataRow In dt.Rows
        fecha1 = CDate(dr.Item(0))
        fecha2 = CDate(dr.Item(18))
        strfecha1 = fecha1.ToString("yyyyMMdd hh:mm:ss tt").Replace(".", "")
        strfecha2 = fecha2.ToString("yyyyMMdd hh:mm:ss tt").Replace(".", "")
        selSQL = "insert into ttransactionlog1 ([OccurDateTime],[NodeID],[Kind],[UUID],[UserID],[FirstName],[LastName],[MI],[Department],[Rank],[CardID],[CreateDateTime],[LeftRight],[HD],[RotationDegree],[StableTimeInterval],[DecisionTimeInterval],[Message],[PIN]) values " + _
            "('" + strfecha1 + "'," + _
            dr.Item(1).ToString + "," + _
            dr.Item(2).ToString + "," + _
            dr.Item(4).ToString + ",'" + _
            dr.Item(3).ToString + "','" + _
            dr.Item(5).ToString + "','" + _
            dr.Item(6).ToString + "','" + _
            dr.Item(7).ToString + "','" + _
            dr.Item(8).ToString + "','" + _
            dr.Item(9).ToString + "','" + _
            dr.Item(10).ToString + "','" + _
            strfecha2 + "'," + _
            dr.Item(16).ToString + "," + _
            dr.Item(14).ToString + "," + _
            dr.Item(15).ToString + "," + _
            dr.Item(12).ToString + "," + _
            dr.Item(13).ToString + ",'" + _
            dr.Item(11).ToString + "'," + _
            dr.Item(17).ToString + ")"
        daSQL.InsertCommand = New SqlCommand(selSQL, cSQL)
        'cSQL.Open()
        'daSQL.InsertCommand.ExecuteNonQuery()
        'cSQL.Close()
        'DataGridView1.Rows.Insert(0, dr.ItemArray)
        'If DataGridView1.Rows.Count > 10 Then
        '    DataGridView1.Rows.RemoveAt(10)
        'End If
        procesar = New Thread(AddressOf Me.actGrilla)
        procesar.IsBackground = True
        procesar.Start(dr)
        'actGrilla(dr)
    Next

挿入されたデータ行を一番上の位置に表示し、最大 10 個のレコードを画面に表示する DGV を更新したいので、この方法で新しいスレッドにサブを作成しようとしています。

Sub actGrilla(ByVal dr As DataRow)
    If InvokeRequired Then
        Dim uud As New llamaactGrilla(AddressOf actGrilla)
        Invoke(uud, dr)
    Else
        DataGridView1.Rows.Insert(0, dr.ItemArray)
        If DataGridView1.Rows.Count > 10 Then
            DataGridView1.Rows.RemoveAt(10)
        End If
        DataGridView1.Refresh()
    End If
End Sub

私の問題は、この方法を試してみると、コードは常にinvokeRequired trueになり、メモリ障害(約5000レコード)で崩壊し、スレッドなしでやろうとすると、最終的にプログラムのサイクル内に「else」コードを書くことですcotextswitchdeadlock で崩壊します。

私が間違っていることは何ですか?

4

2 に答える 2

1

少しの調査で問題は解決しました。

1位。サイクルを thead 呼び出しに置き換えます。

    If dt.Rows.Count > 0 Then
        procesar = New Thread(AddressOf procesoFondo)
        procesar.Start(dt)
    End If

2番目。新しい関数「procesoFondo」にサイクルを入れます。SQL DB にコードを挿入する行はここにあります。新しいサブデリゲートを呼び出すサイクルに入れます。

    Dim daSQL As New SqlDataAdapter

    Dim cSQL As New SqlConnection(conSQL)
    Dim fecha1, fecha2 As Date
    Dim strfecha1, strfecha2 As String
    For Each dr As DataRow In dt.Rows
        fecha1 = CDate(dr.Item(0))
        fecha2 = CDate(dr.Item(18))
        strfecha1 = fecha1.ToString("yyyyMMdd hh:mm:ss tt").Replace(".", "")
        strfecha2 = fecha2.ToString("yyyyMMdd hh:mm:ss tt").Replace(".", "")
        selSQL = "insert into ttransactionlog1 ([OccurDateTime],[NodeID],[Kind],[UUID],[UserID],[FirstName],[LastName],[MI],[Department],[Rank],[CardID],[CreateDateTime],[LeftRight],[HD],[RotationDegree],[StableTimeInterval],[DecisionTimeInterval],[Message],[PIN]) values " + _
            "('" + strfecha1 + "'," + _
            dr.Item(1).ToString + "," + _
            dr.Item(2).ToString + "," + _
            dr.Item(4).ToString + ",'" + _
            dr.Item(3).ToString + "','" + _
            dr.Item(5).ToString + "','" + _
            dr.Item(6).ToString + "','" + _
            dr.Item(7).ToString + "','" + _
            dr.Item(8).ToString + "','" + _
            dr.Item(9).ToString + "','" + _
            dr.Item(10).ToString + "','" + _
            strfecha2 + "'," + _
            dr.Item(16).ToString + "," + _
            dr.Item(14).ToString + "," + _
            dr.Item(15).ToString + "," + _
            dr.Item(12).ToString + "," + _
            dr.Item(13).ToString + ",'" + _
            dr.Item(11).ToString + "'," + _
            dr.Item(17).ToString + ")"

        'Inserta el dato en SQL
        daSQL.InsertCommand = New SqlCommand(selSQL, cSQL)
        cSQL.Open()
        daSQL.InsertCommand.ExecuteNonQuery()
        cSQL.Close()

        'Llama invocacion de llenado de gridview
        add_datos_gv(dr)

        'Llama invocacion estado proceso
        estado_hilo()
    Next

デリゲート (スレッドの状態を示すラベルの場合は 1+) は.

Delegate Sub set_gv(ByVal dr As DataRow)
Delegate Sub set_lb()

最後に、代理人は DGV の情報を更新します。

 Private Sub add_datos_gv(ByVal dr As DataRow)
    If DataGridView1.InvokeRequired Then
        Dim d As New set_gv(AddressOf add_datos_gv)
        Invoke(d, dr)
    Else
        DataGridView1.Rows.Insert(0, dr.ItemArray)
        If DataGridView1.Rows.Count > 10 Then
            DataGridView1.Rows.RemoveAt(10)
        End If
    End If
End Sub

Private Sub estado_hilo()
    If Label1.InvokeRequired Then
        Dim l As New set_lb(AddressOf estado_hilo)
        Invoke(l)
    Else
        Label1.Text = procesar.ThreadState.ToString
    End If
End Sub
于 2013-05-02T15:32:01.500 に答える