0

マシンのデータをポーリングするマルチスレッド プログラムを作成しようとしていますが、正しく動作していないようです。以下のコードは機能しており、本来の 4 つのスレッドを作成していますが、コードの流れはメインの UI スレッドで連続して発生しているようです。

私が達成しようとしているのは、UI をロックすることなく、データグリッドの各行を同時に更新することです。

以下は私が持っているものの単純化されたバージョンですが、問題を示すのに役立ちます. 参考までに、「testclass」は、各クラス要素がマシンのプロパティを表すマシンのインスタンスとして使用されるクラスです。

問題を説明するのに十分な情報を提供したことを願っています。前もって感謝します。

Psフォームを更新する必要はありませんか?

Imports System.Threading

Public Class TestForm

Public threadcount As Integer
Public Delegate Sub testclassDelegate(test As Object)

Private Class testclass
    Public index As Integer
    Public TestVal1 As Integer = 100
    Public TestVal2 As Integer = 200
    Public TestVal3 As Integer = 300
    Public TestVal4 As Integer = 400
    Public TestVal5 As Integer = 500
    Public TestVal6 As Integer = 600
    Public testDel As testclassDelegate
End Class

Private Sub TestForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For i As Integer = 0 To 3
        DataGridView1.Rows.Add()
        DataGridView1.Rows(i).Cells(0).Value = i + 1
    Next
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    For i As Integer = 0 To 3
        DataGridView1.Rows(i).Cells(1).Value = ""
        DataGridView1.Rows(i).Cells(2).Value = ""
        DataGridView1.Rows(i).Cells(3).Value = ""
        DataGridView1.Rows(i).Cells(4).Value = ""
        DataGridView1.Rows(i).Cells(5).Value = ""
        DataGridView1.Rows(i).Cells(6).Value = ""
    Next
    Poll_FreeThread()
End Sub

Private Sub Poll_FreeThread()
    For i As Integer = 0 To DataGridView1.Rows.Count - 1
        Dim test As New testclass
        test.index = i
        test.testDel = AddressOf UIUpdate

        Interlocked.Increment(threadcount)
        Me.Label2.Text = threadcount
        Try
            Dim thPoll As New Thread(Sub() invokeUIUpdate(test))
            thPoll.IsBackground = True
            thPoll.Priority = ThreadPriority.BelowNormal
            thPoll.Start()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    Next
End Sub

Public Sub invokeUIUpdate(test As Object)
    If DataGridView1.InvokeRequired Then
        DataGridView1.Invoke(New testclassDelegate(AddressOf UIUpdate), test)
    Else
        UIUpdate(test)
    End If
End Sub

Public Sub UIUpdate(test As Object)
    Thread.Sleep(test.index * 100)
    DataGridView1.Rows(test.index).Cells(1).Value = test.TestVal1
    Me.Refresh()
    Thread.Sleep(100)
    DataGridView1.Rows(test.index).Cells(2).Value = test.TestVal2
    Me.Refresh()
    Thread.Sleep(100)
    DataGridView1.Rows(test.index).Cells(3).Value = test.TestVal3
    Me.Refresh()
    Thread.Sleep(100)
    DataGridView1.Rows(test.index).Cells(4).Value = test.TestVal4
    Me.Refresh()
    Thread.Sleep(100)
    DataGridView1.Rows(test.index).Cells(5).Value = test.TestVal5
    Me.Refresh()
    Thread.Sleep(100)
    DataGridView1.Rows(test.index).Cells(6).Value = test.TestVal6
    Me.Refresh()
    Interlocked.Decrement(threadcount)
    Me.Label2.Text = threadcount
End Sub

End Class
4

2 に答える 2

-1

DoWorkEventHandler と RunWorkerCompletedEventHandler のイベントで timer と backgroundworker を使用できます。

例: C# の例:

private void Button1_Click(object sender, EventArgs e)
{
workerThreadForLetters.WorkerReportsProgress = true;                    workerThreadForLetters.WorkerSupportsCancellation = true;
workerThreadForLetters.DoWork -= new DoWorkEventHandler(workerThreadForLetters_DoWork);
workerThreadForLetters.DoWork += new DoWorkEventHandler(workerThreadForLetters_DoWork);

workerThreadForLetters.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(workerThreadForLetters_RunWorkerCompleted);

workerThreadForLetters.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerThreadForLetters_RunWorkerCompleted);
}
    private void workerThreadForLetters_DoWork(object sender, DoWorkEventArgs e)
    {
               //DO SOMETHING
    }
    private void workerThreadForLetters_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
             //DO AS REQUIRED
             Timer1.enable = false;
    }
    private void tmCollectionLettersUpdate_Tick(object sender, EventArgs e)
    {
             //Content update like % of data progressed or any.
    }
于 2013-07-15T12:36:16.267 に答える