azza452
azza452

Reputation: 25

Prevent "Not Responding"

When running code on a Form, sometimes (usually when looping) the program title displays "Not Responding" even though its still running fine.

In my case, I'm looping and filling an array > array to DataTable > DataTable to DataGridView.

example:

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

I read somewhere that I should be using threads? or BackgroundWorker but I'm unsure how to use these here like a lot of questions point to BackgroundWorker Class.

But I don't understand C#.

Upvotes: 0

Views: 159

Answers (1)

Joel Coehoorn
Joel Coehoorn

Reputation: 415901

The first thing to do is to drop a BackgroundWorker component onto the form. Click on the component and setup handlers for the DoWork, RunWorkerCompleted, and ProgressChanged events. Then, assuming you use all the default names, your code will look like this:

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

This is the basic example. You can also use this to do things like report progress and make sure it's not already busy before starting it. More information (including samples in C#, but translates to VB.Net easily) is here:

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

Upvotes: 1

Related Questions