Edo Spahić
Edo Spahić

Reputation: 21

vb.net threading sub slower than call sub

I know this Question was already posted, but it was never really answered, or I did not understand the answer :)

My Problem is that when I call this Sub within the Thread, it takes about 4 sec to execute the code, but if I make a simple Call Sub (Like commented in Code) it takes about 450 ms.

I have a simple program with 2 Subs:

  1. To report Progress on Main Form

  2. To do some "For" Looping

    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
    

I have tried to take out Progress Reporting but the Result is the same.

I hope you have some suggestions or solutions for me. I would be very thankful.

Upvotes: 1

Views: 77

Answers (2)

Edo Spahić
Edo Spahić

Reputation: 21

Just wanted to report that I found a solution.

The main problem was this line of code in:

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

So if I start this Sub from another Thread rather than from a Main Thread, for every single loop it has to go to main thread and to take Paramater from TextBox and to go back in Thread to Loop further.

I took that out, declared a variable at the begining and assigned this TextBox value to it and it works like charm.

Also I took a suggestion from dbasnett to Invoke Reporting every time without If-Else and also the suggestion from Steven Doggart to Report every 100 Loops.

You guys helped a lot. Thanks for that!!

Upvotes: 0

dbasnett
dbasnett

Reputation: 11773

Give these changes a try

Change this

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

to

            ReportProgress(Progr)

And change method ReportProgress to

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

See if that makes a difference. The check for InvokeRequired is not needed, the answer is always yes.

Upvotes: 1

Related Questions