Reputation: 21
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:
To report Progress on Main Form
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
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
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