Предотвратить "не отвечать" - PullRequest
0 голосов
/ 29 мая 2020

При запуске кода в форме иногда (обычно при зацикливании) в заголовке программы отображается «Не отвечает», хотя она все еще работает нормально.

В моем случае я зацикливаю и заполняю массив> массив в DataTable> DataTable в DataGridView.

пример:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim ArrayNew(1000001, 2) As Object

    For i = 0 To 1000000
        For j = 0 To 1
            ArrayNew(i, j) = "TEST"
        Next j
    Next i

    Table1 = New DataTable("EXAMPLETABLE")
    Table1.Columns.Add("COLUMN1")
    Table1.Columns.Add("COLUMN2")
    Table1.Columns.Add("COLUMN3")

    Dim RowNo As Integer = 0
    Do
        Table1.Rows.Add(New String() {RowNo + 1, ArrayNew(RowNo, 0), ArrayNew(RowNo, 1)})
        RowNo = RowNo + 1
    Loop Until ArrayNew(RowNo, 1) = ""

    DataGridView1.DataSource = Table1

End Sub

Я где-то читал, что мне следует использовать потоки? или BackgroundWorker, но я не уверен, как их использовать, поскольку многие вопросы указывают на BackgroundWorker Class .

Но я не понимаю C#.

1 Ответ

1 голос
/ 29 мая 2020

Первое, что нужно сделать, это добавить в форму компонент BackgroundWorker. Щелкните компонент и настройте обработчики событий DoWork, RunWorkerCompleted и ProgressChanged. Затем, если вы используете все имена по умолчанию, ваш код будет выглядеть так:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    backgroundWorker1.RunWorkerAsync()
End Sub

Private Sub backgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles backgroundWorker1.DoWork
    Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    Dim Table1 As New DataTable("EXAMPLETABLE")
    Table1.Columns.Add("COLUMN1")
    Table1.Columns.Add("COLUMN2")
    Table1.Columns.Add("COLUMN3")

    Dim Size As Integer = 1000000
    For i As Integer = 1 To Size
        Table1.Rows.Add(New String() {i.ToString(), "Test", "Test"})
        If i Mod 50 = 0 Then
            worker.ReportProgress(i * 100.0 / Size) 'Report as a percentage of the total
        End If
    Next
    e.Result = Table1
End Sub

Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
    DataGridView1.DataSource = DirectCast(e.Result, DataTable)
End Sub

Private Sub backgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles backgroundWorker1.ProgressChanged
        'Check e.ProgressPercentage here
End Sub

Это базовый пример c. Вы также можете использовать это, чтобы делать такие вещи, как отчет о прогрессе и убедиться, что он еще не занят, прежде чем запускать его. Дополнительная информация (включая образцы в C#, но легко переводится на VB. Net) находится здесь:

https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker?view=netcore-3.1

...