Почему мое событие автозаполнения текстового поля TextChanged работает так медленно с VB.NET

Я пытаюсь выполнить автозаполнение с помощью события текстового поля TextChanged, но с VB.NET работаю так медленно.

хотя записей всего 6, что-то не так с моим кодом, подскажите, пожалуйста.

Я прикрепил гифку с примером файла, когда я набрал «KBE», он работал очень медленно, и я выдавал некоторые предложения, пока он не завершился сам, а затем я попробовал набрать «KBT», он тоже работал очень медленно. и придумывайте несколько предложений, пока все не закончится само собой

Спасибо

Public Class Form3
    Private iService As New ItemService()
    Private bindingSource1 As BindingSource = Nothing
    Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        lblcodeproduct.Visible = False
        TextBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend
        TextBox1.AutoCompleteSource = AutoCompleteSource.CustomSource
        TextBox1.AutoCompleteCustomSource.AddRange(iService.GetByCodeProduct().Select(Function(n) n.CodeProduct).ToArray())
    End Sub
    Private Sub GetItemData2(ByVal iditem As String)
        Dim item = iService.GetByCodeProductOrBarcode(iditem)
        If item IsNot Nothing Then
            If String.Equals(iditem, item.CodeProduct, StringComparison.CurrentCultureIgnoreCase) Then
                TextBox1.Text = item.CodeProduct
            End If
            TextBox2.Text = item.Barcode
        Else
            TextBox2.Clear()
            Return
        End If
    End Sub
    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        If TextBox1.Text = "" Then
            lblcodeproduct.Visible = False
            ErrorProvider1.SetError(TextBox1, "")
        Else
            bindingSource1 = New BindingSource With {.DataSource = New BindingList(Of Stock)(CType(iService.GetByCodeProductlike(TextBox1.Text), IList(Of Stock)))}

            If bindingSource1.Count > 0 Then

                lblcodeproduct.Visible = False

                ErrorProvider1.SetError(TextBox1, "")
            Else
                lblcodeproduct.Visible = True
            End If
            GetItemData2(TextBox1.Text)
        End If
    End Sub
End Class
Public Class Stock
    Public Property Id() As Integer
    Public Property CodeProduct() As String
    Public Property Barcode() As String
End Class
Public Class ItemService
    Public Function GetOledbConnectionString() As String

        Return "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\TRIAL.accdb;Persist Security Info=False;"
    End Function
    Private ReadOnly _conn As OleDbConnection
    Private _connectionString As String = GetOledbConnectionString()
    Public Sub New()
        _conn = New OleDbConnection(_connectionString)
    End Sub
    Public Function GetByCodeProduct() As IEnumerable(Of Stock)
        Dim sql = "SELECT CodeProduct AS CodeProduct FROM Items"
        Using _conn = New OleDbConnection(GetOledbConnectionString())
            Return _conn.Query(Of Stock)(sql).ToList()
        End Using
    End Function
    Public Function GetByCodeProductlike(ByVal CodeProduct As String) As IEnumerable(Of Stock)
        Dim sql = $"SELECT CodeProduct FROM Items WHERE CodeProduct LIKE '%" & CodeProduct & "%'"
        Using _conn = New OleDbConnection(GetOledbConnectionString())
            Return _conn.Query(Of Stock)(sql).ToList()
        End Using
    End Function
    Public Function GetByCodeProductOrBarcode(ByVal code As String) As Stock
        Dim sql = $"SELECT * FROM Items WHERE CodeProduct = '{code}' or Barcode = '{code}'"
        Using _conn = New OleDbConnection(GetOledbConnectionString())
            Return _conn.Query(Of Stock)(sql).FirstOrDefault()
        End Using
    End Function
End Class

РЕЗУЛЬТАТ АВТОЗАПОЛНЕНИЕ ТЕКСТА

Можете ли вы поделиться образцом данных (вашим TRIAL.accdb) и рассказать нам, что вы используете для чтения своего файла (это System.Data.OleDb?). Функция запроса также отсутствует в коде, которым вы поделились.

SioGabx 04.04.2024 13:36

Не следует запрашивать базу данных при каждом событии TextChanged. Если вы собираетесь вводить «KBE», какой смысл искать по первым двум символам? Вот что замедляет его. Вам следует запустить/перезапустить Timer по событию TextChanged и выполнить поиск по событию Tick. Вы можете установить Interval так, чтобы время между нажатиями клавиш не истекало, когда кто-то печатает, а начиналось вскоре после того, как он остановится. Примерно 300–500 миллисекунд должно подойти, но вы можете поэкспериментировать, чтобы увидеть, что работает лучше всего.

jmcilhinney 04.04.2024 14:35

@SioGabx, спасибо. за ваш ответ. Я горжусь, что вы пытаетесь найти решение для меня. ссылка это ссылка на образец данных TRIAL.accdb . tell us what you are using to read your file (is it System.Data.OleDb?). Вы правы, это System.Data.OleDb

roy 04.04.2024 16:30

@SioGabx, а для Query function is also missing in the code you shared я использую Dapper nuget

roy 04.04.2024 16:31

@SioGabx, извините за беспокойство, у меня есть новый пост, возможно, вы мне поможете. Для этого ссылка

roy 06.04.2024 03:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас есть рекурсивные вызовы события TextChanged, поскольку GetItemData2 может изменить TextBox1. Я отметил изменения, которые я сделал, с помощью '<<<<<<<<<<<<<<<<<<<<<<<<<.

ОТРЕДАКТИРОВАНО - см. комментарии

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    Static recursive As Boolean = False '<<<<<<<<<<<<<<<<<<<<<<<<<
    If recursive Then Exit Sub '<<<<<<<<<<<<<<<<<<<<<<<<<
    recursive = True '<<<<<<<<<<<<<<<<<<<<<<<<<
    If TextBox1.Text = "" Then
        lblcodeproduct.Visible = False
        ErrorProvider1.SetError(TextBox1, "")
        recursive = False '<<<<<<<<<<<<<<<<<<<<<<<<<
    Else
        Try '<<<<<<<<<<<<<<<<<<<<<<<<<
            bindingSource1 = New BindingSource With {.DataSource = New BindingList(Of Stock)(CType(iService.GetByCodeProductlike(TextBox1.Text), IList(Of Stock)))}

            If bindingSource1.Count > 0 Then

                lblcodeproduct.Visible = False

                ErrorProvider1.SetError(TextBox1, "")
            Else
                lblcodeproduct.Visible = True
            End If
            ' the following method might change TextBox1
            '  which results in the .TextChanged event being called again
            ' the changes mean that second call stops the processing of the .TextChanged event
            GetItemData2(TextBox1.Text)
        Finally '<<<<<<<<<<<<<<<<<<<<<<<<<
            recursive = False '<<<<<<<<<<<<<<<<<<<<<<<<<
        End Try
    End If
End Sub

Возможно, было бы лучше иметь recursive = False внутри Finally, чтобы гарантировать, что это произойдет при выходе по любой причине (и для защиты от неосторожного раннего выхода, который может быть добавлен позже).

Craig 04.04.2024 16:25

@Craig, It might be better to have the recursive = False inside a Finally to ensure that it happens when exiting for any reason (and to protect against a careless early exit that might be added later). ты имеешь в виду использование try catch finally

roy 04.04.2024 16:34

@Крейг - Я согласен. Я отредактирую свой ответ.

dbasnett 04.04.2024 16:44

@user23548857 user23548857 Для этой цели Catch не нужен, если только вы не хотите что-то с ним сделать — я бы посоветовал по умолчанию не включать Catch. Цель состоит лишь в том, чтобы Finally гарантировать, что вам не нужно помнить о включении recursive = False в каждой точке выхода (и вы застрахованы в случае исключения, которое обрабатывается на более высоком уровне в программе без ее сбоя).

Craig 04.04.2024 17:08

@Craig - за все миллионы лет, что я делал это, я не знал, что попытка может существовать без подвоха. Я видел, если у тебя нет подвоха, значит, у тебя должен быть наконец. СПАСИБО.

dbasnett 04.04.2024 18:16

Другие вопросы по теме