user9252202
user9252202

Reputation: 25

Form Loads slowly in vb.net

I am currently working in ERP project on vb.net. I want to load product data in a textbox on form load. I am using autocomplete method but having a data of around 26000 the form loads slowly for 4 mins. Is there any way to avoid this or is there any way to call this function in background when the application starts?

This is my autocomplete textbox code. It works fine but it hangs alot as of the data is so large.

 Private Sub pn()
     Try
        con = Class1.dbconn
        Dim dt As New DataTable
        Dim ds As New DataSet
        ds.Tables.Add(dt)
        Dim da As New SqlDataAdapter("select [Part Name] from 
                                      Part_Master_Download$", con)
        da.Fill(dt)
        Dim r As DataRow
        TextBox9.AutoCompleteCustomSource.Clear()
        For Each r In dt.Rows
            TextBox9.AutoCompleteCustomSource.Add(r.Item(0).ToString)

        Next
        con.Close()

    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

the properties of the textbox should be set to true for autocompletetextbox

Upvotes: 1

Views: 677

Answers (2)

jmcilhinney
jmcilhinney

Reputation: 54457

Don't populate the AutoCompleteCustomSource in a loop. Populate an array first and then load the list in one go with a single call to AddRange:

Dim items = dt.Rows.Cast(Of DataRow)().
                    Select(Function(row) CStr(row(0)).
                    ToArray()

TextBox9.AutoCompleteCustomSource.AddRange(items)

You should find that that speeds things up considerably. If there's still a problem with performance, we can look a bit further.

EDIT: To prove my point, I just tested the following code:

Public Class Form1

    Private timer As Stopwatch

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        timer = Stopwatch.StartNew()

        Dim rng As New Random

        Dim a = Convert.ToInt32("a"c)
        Dim z = Convert.ToInt32("z"c)
        Dim items = Enumerable.Range(1, 26000).Select(Function(n) Convert.ToChar(rng.Next(a, z + 1)).ToString())

        For Each item In items
            TextBox1.AutoCompleteCustomSource.Add(item)
        Next
    End Sub

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        MessageBox.Show(timer.Elapsed.ToString())
    End Sub

End Class

and the message displayed "00:03:08.3167858", i.e. just over three minutes to load the list. I then changed the Load event handler to this:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    timer = Stopwatch.StartNew()

    Dim rng As New Random

    Dim a = Convert.ToInt32("a"c)
    Dim z = Convert.ToInt32("z"c)
    Dim items = Enumerable.Range(1, 26000).Select(Function(n) Convert.ToChar(rng.Next(a, z + 1)).ToString())

    TextBox1.AutoCompleteCustomSource.AddRange(items.ToArray())
End Sub

so a single call to AddRange instead of calling Add in a loop, and the message was "00:00:00.0557427", i.e. just under 56 milliseconds. Is that better?

Upvotes: 4

Sulieman Mansouri
Sulieman Mansouri

Reputation: 579

You can use paging to control the amount of returned data. Check this link for detailed examples. Another way is to use (Task Async and await) so you won't lock your UI.

Here is a few last suggestions not related directly to the question but might help clean the code a bit:

you can skip the dataset and use the datatable directly, you don't need it for just one table.

Bind your results in the datatable to a datagridview or a combobox instead of iterating through your results and filling a textbox.

cheers

Upvotes: 0

Related Questions