vb.net продвигает подпрограмму медленнее, чем вызывает подпрограмму - PullRequest
0 голосов
/ 28 августа 2018

Я знаю, что этот Вопрос уже был опубликован, но на него так и не был дан ответ, или я не понял ответа:)

Моя проблема в том, что когда я вызываю этот Sub в потоке, выполнение кода занимает около 4 секунд, но если я выполняю простой вызов Sub (как прокомментировано в коде), это занимает около 450 мс.

У меня есть простая программа с 2 подпрограммами:

  1. Чтобы сообщить о прогрессе в основной форме

  2. Чтобы сделать цикл "Для"

    Imports System.Data.SqlClient
    
    Public Class Form1
    Public Delegate Sub ProzentDelegate(ByVal Prozent As Double)
    
    Dim G_I_Temp As Integer = 0
    Dim G_S_Prüfziffer As String
    Dim G_S_Präfix As String
    Dim G_I_Zähler As Integer
    Dim G_I_Stellen As Integer
    Dim G_D_Step As Integer = 1
    Dim G_I_Position As Integer
    Dim DT_G_Prüftabelle As DataTable
    Dim DR_G_Prüftabelle As DataRow
    Dim thisLock As New Object
    Dim conn As String = "Data Source=SR-SQLWVS;Initial Catalog=Barcode;Integrated Security=True"
    Dim sourceconn As New SqlConnection(conn)
    Dim adap As SqlDataAdapter
    Dim cmd As SqlCommand = New SqlCommand("SELECT TOP(10) * FROM dbo.Prüf_Tabelle", sourceconn)
    
    Dim Thrd_preview As Threading.Thread
    
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
        sourceconn.Open()
    
        cmd.Connection = sourceconn
    End Sub
    
    Public Sub ReportProgress(ByVal Prozent As Double)
        ProgressBar1.Value = Prozent
    End Sub
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If RB_Thread.Checked Then
    
            If Thrd_preview IsNot Nothing Then Thrd_preview = Nothing
            Thrd_preview = New Threading.Thread(AddressOf DoSomeWork)
            Thrd_preview.IsBackground = True
            Thrd_preview.Start()
    
        Else
            DoSomeWork()
        End If
    End Sub
    
    Private Sub DoSomeWork()
    
    
        Dim ds As New DataSet
        DT_G_Prüftabelle = ds.Tables.Add("Prüf_Tabelle")
    
        Dim L_I_Counter, L_I_Counter2 As Integer
        Dim L_I_Ende As Integer
        Dim L_I_Step As Integer
        Dim L_I_Nutzen As Integer = 1
        L_I_Step = 1
        L_I_Ende = Val(TB_Auftrag_neu_Anzahl.Text)
        G_I_Stellen = 8
        G_S_Prüfziffer = "1"
        G_S_Präfix = "00"
        If TB_Info_Increment.Text = "" Then TB_Info_Increment.Text = 1
    
    
    
    
    adap = New SqlDataAdapter("SELECT TOP(10) * FROM dbo.Prüf_Tabelle", sourceconn)
    
        adap.FillSchema(DT_G_Prüftabelle, SchemaType.Mapped)
    
        DT_G_Prüftabelle.Rows.Clear()
    
        Dim pre As Date = Now
    
        For L_I_Counter = 1 To (L_I_Ende * L_I_Step) Step L_I_Step
            For L_I_Counter2 = 1 To L_I_Nutzen
                DR_G_Prüftabelle = DT_G_Prüftabelle.NewRow
                DR_G_Prüftabelle.Item("Auftrag_Lfd_nr") = TB_KeyLot.Text
                DR_G_Prüftabelle.Item("Position") = G_I_Position
                G_I_Position += G_D_Step
                DR_G_Prüftabelle.Item("Barcode_soll") = F_Berechnung((Trim(Str(Val(TB_Auftrag_neu_Von.Text) + L_I_Counter - 1))).PadLeft(G_I_Stellen, "0"))
                DT_G_Prüftabelle.Rows.Add(DR_G_Prüftabelle)
    
            If ProgressBar1.InvokeRequired Then
                ProgressBar1.BeginInvoke(New ProzentDelegate(AddressOf ReportProgress), (L_I_Counter * 100) / (L_I_Ende * L_I_Step))
            Else
                ReportProgress((L_I_Counter * 100) / (L_I_Ende * L_I_Step))
            End If
    
            Next
    
    
    
        Next
    
    
        MsgBox(Now.Subtract(pre).TotalMilliseconds.ToString & " ms.")
    
    
    End Sub
    
    
    Function F_Berechnung(ByVal L_Nummer As String) As String
        Dim L_B_Gerade As Boolean = False
        Dim L_I_Prüfziffer As Integer
        Dim L_I_Stellen As Integer
        Me.G_I_Temp = 0
    
    Select Case G_S_Prüfziffer
        Case "0"
            F_Berechnung = L_Nummer
        Case "1"
            F_Berechnung = G_S_Präfix & Trim(L_Nummer)
        Case "2"
            F_Berechnung = G_S_Präfix & Trim(L_Nummer)
        Case "3"
            F_Berechnung = L_Nummer
            '
        Case "5"    '-----Mod 10 gewichtung 31...-----
            L_Nummer = G_S_Präfix & Trim(L_Nummer)
            L_I_Stellen = Len(L_Nummer)
            For Me.G_I_Zähler = L_I_Stellen To 1 Step -1
                Me.G_I_Temp += Val(Mid(L_Nummer, Me.G_I_Zähler, 1)) * IIf(L_B_Gerade, 1, 3)
                L_B_Gerade = Not L_B_Gerade
            Next
            L_I_Prüfziffer = IIf(10 - Me.G_I_Temp Mod 10 = 10, 0, 10 - Me.G_I_Temp Mod 10)
            F_Berechnung = Trim(L_Nummer) & Trim(Str(L_I_Prüfziffer))
            '
        Case "6"    '-----Mod 10 gewichtung 13...-----
            L_Nummer = G_S_Präfix & Trim(L_Nummer)
            L_I_Stellen = Len(L_Nummer)
            For Me.G_I_Zähler = L_I_Stellen To 1 Step -1
                Me.G_I_Temp += Val(Mid(L_Nummer, Me.G_I_Zähler, 1)) * IIf(L_B_Gerade, 3, 1)
                L_B_Gerade = Not L_B_Gerade
            Next
            L_I_Prüfziffer = IIf(10 - Me.G_I_Temp Mod 10 = 10, 0, 10 - Me.G_I_Temp Mod 10)
            F_Berechnung = Trim(L_Nummer) & Trim(Str(L_I_Prüfziffer))
            '
    
    
        Case Else
            F_Berechnung = L_Nummer
    
    End Select
    
    End Function
    

Я пытался получить отчет о прогрессе, но результат тот же.

Я надеюсь, у вас есть предложения или решения для меня. Я был бы очень благодарен.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Просто хотел сообщить, что нашел решение.

Основной проблемой была эта строка кода в:

DR_G_Prüftabelle.Item("Auftrag_Lfd_nr") = TB_KeyLot.Text

Так что, если я запускаю этот Sub из другого потока, а не из основного потока, для каждого отдельного цикла он должен перейти в основной поток и взять Paramater из TextBox и вернуться в Thread to Loop дальше.

Я взял это, объявил переменную в начале и присвоил ей значение TextBox, и оно работает как шарм.

Также я принимал предложение от dbasnett к Invoke Reporting каждый раз без If-Else, а также предложение от Стивена Доггарта сообщать о каждых 100 циклах.

Вы, ребята, очень помогли. Спасибо за это !!

0 голосов
/ 28 августа 2018

Попробуйте эти изменения

Изменить это

        If ProgressBar1.InvokeRequired Then
            ProgressBar1.Invoke(New ProzentDelegate(AddressOf ReportProgress), Progr)
        Else
            ReportProgress(Progr)
        End If

до

            ReportProgress(Progr)

И изменить метод ReportProgress на

Public Sub ReportProgress(ByVal Prozent As Double)
    Me.BeginInvoke(Sub()
                       ProgressBar1.Value = Prozent
                   End Sub)
End Sub

Посмотрите, имеет ли это значение. Проверка на InvokeRequired не нужна, ответ всегда да.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...