Working code fails when run as backgroundworker - vb.net

I am developing a client app on my PC. I have several modules connected to my network. The modules are boards I have designed which act as servers. I want the client to do a scan of the network every 15 seconds to see if there have been any new servers added to the network and if so, log them into the MySQL database and to determine which of the servers already logged to the database as online. Ones in the database which are offline are shown on a treeview in red, online in green so if a board goes down, I can check if it has failed or the cable damaged or some other reason for being off.
OK, this is the sub that does the scan
Public Sub ScanModules()
Dim Mdc As ADODB.Command
Dim Sr As ADODB.Recordset
Dim check As String
Dim modsonline As Integer = 0
Dim l, a, b As Integer
Dim repdelay As Integer = 100
Dim result As Integer = 0
Dim myser As String
Dim scantime As String = Date.Today.Date & " at " & TimeOfDay.ToString("h:mm:ss")
Dim modtype As String
Dim serno As String
Dim ismod As Boolean
If My.Computer.Network.IsAvailable Then
' get the ARP table and parse it to see all IP and MAC addresses currently registered
Dim sCommand As String = "arp"
Dim sArgs As String = "-a"
Dim psi As System.Diagnostics.ProcessStartInfo = New System.Diagnostics.ProcessStartInfo(sCommand, sArgs)
psi.UseShellExecute = False
psi.RedirectStandardOutput = True
psi.CreateNoWindow = True
arptable = ""
Dim proc As System.Diagnostics.Process = System.Diagnostics.Process.Start(psi)
arptable = proc.StandardOutput.ReadToEnd
l = Len(arptable)
a = 90
b = 112
Mdc = New ADODB.Command
Mdc.let_ActiveConnection(DBCon)
Mdc.CommandType = ADODB.CommandTypeEnum.adCmdText
Mdc.CommandText = "SELECT * from machine"
Sr = Mdc.Execute
nummacs = Sr.RecordCount
' look for Baart modules in the ARP table - MAC will start ea and be all decimal numbers
Do While b < l
myip = RTrim(Mid(arptable, a, 15))
mymac = Mid(arptable, b, 17)
If VB.Left(mymac, 2) = "ea" Then
ismod = True
check = Mid(mymac, 4, 2) & Mid(mymac, 7, 2) & Mid(mymac, 10, 2) & Mid(mymac, 13, 2) & Mid(mymac, 16, 2)
For z = 1 To 10
If Asc(Mid(check, z, 1)) > 57 Then ismod = False
Next
If ismod Then
Cmd = New ADODB.Command
Mdc.let_ActiveConnection(DBCon)
Mdc.CommandType = ADODB.CommandTypeEnum.adCmdText
Mdc.CommandText = "SELECT * from modules WHERE macaddr = '" & mymac & "'"
Sr = Mdc.Execute
If Sr.RecordCount = 0 Then 'module is not in database, add it
EthMsg = ""
sendmsg("ENQ", myip)
If EthMsg = "ACK" Then ' if reply is not ACK then either not a Baart or not actually online
EthMsg = ""
modsonline = modsonline + 1
sendmsg("SER", myip)
serno = EthMsg
EthMsg = ""
sendmsg("TYP", myip)
modtype = EthMsg
EthMsg = ""
sendmsg("EOT", myip)
If EthMsg = "ACK" Then
Mdc.CommandText = "INSERT INTO modules (macaddr, serno, modtype, ipaddr, active, assigned) VALUES ('"
Mdc.CommandText = Mdc.CommandText & mymac & "','" & serno & "','" & modtype & "','" & myip & "', 1, 0 )"
Mdc.Execute()
Mdc.CommandText = "SELECT * from modules WHERE macaddr = '" & mymac & "'"
Sr = Mdc.Execute
End If
End If
Else
Mdc.CommandText = "UPDATE modules set ipaddr = '" & myip & "', active = '1' WHERE macaddr = '" & mymac & "'"
Sr = Mdc.Execute
End If
End If
End If
a = a + 58
b = b + 58
Loop
' now update the module treeview showing which modules are online by pinging them
Mdc.CommandText = "SELECT * from modules"
Sr = Mdc.Execute
If Sr.RecordCount > 0 Then
Sr.MoveFirst()
For a = 0 To Sr.RecordCount - 1
myip = Trim(Sr.Fields.Item("ipaddr").Value)
myser = Sr.Fields.Item("serno").Value
If My.Computer.Network.Ping(myip, 100) Then
Mdc.CommandText = "UPDATE modules set active = '1', lastol = '" & scantime & "' WHERE ipaddr = '" & myip & "'"
Mdc.Execute()
For Each n As TreeNode In frmMain.ModView.Nodes(0).Nodes
If n.Text = myser Then
n.ImageIndex = 6
n.SelectedImageIndex = 6
End If
Next
Else
Mdc.CommandText = "UPDATE modules set active = '0' WHERE ipaddr = '" & myip & "'"
Mdc.Execute()
For Each n As TreeNode In frmMain.ModView.Nodes(0).Nodes
If n.Text = myser Then
n.ImageIndex = 7
n.SelectedImageIndex = 7
End If
Next
End If
Sr.MoveNext()
Next
End If
End If
End Sub
I also have these two subs in my code
Private Sub ScanTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ScanTimer.Tick
'BgdScan.RunWorkerAsync()
Call ScanModules()
Application.DoEvents()
End Sub
Private Sub BgdScan_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BgdScan.DoWork
Call ScanModules()
Application.DoEvents()
End Sub
You will see in ScanTimer_Tick sub I have BgdScan.RunWorkerAsync() commented out so it does not run in the background and this works great. If I unplug a board, it turns red on the treeview within 15 seconds. If I plug it back in it turns green. But if I uncomment BgdScan.RunWorkerAsync() and comment out the next two lines, it should run in the background but it crashes out with an 'ArgumentOutOfRangeException was unhandled by user code' at the line For 'Each n As TreeNode In frmMain.ModView.Nodes(0).Nodes' 22 lines from the bottom of the ScanModules sub. The exception detail is;
System.ArgumentOutOfRangeException was unhandled by user code
Message="Specified argument was out of the range of valid values. Parameter name: index"
ParamName="index"
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.TreeNodeCollection.get_Item(Int32 index)
at BaartOLM.General.ScanModules() in C:\BaartOLM.VBNET\General.vb:line 291
at BaartOLM.frmMain.BgdScan_DoWork(Object sender, DoWorkEventArgs e) in C:\BaartOLM.VBNET\main.vb:line 631
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
InnerException:
I have never used backgroundworker before so this is new to me. Can anyone suggest why this code will run OK in the foreground but not in the background?
Thanks for your help, Steve.

Related

Datagridview - Insert an image into a cell in a specific row

I have a vb.net project where I have a DataGridView (called "dgvRevisiones") to record information about vehicle damage records.
Through an SFTP that I have previously configured, I have the photos of each damage record, my program downloads them in a temporary folder and that works perfect.
The problem is when I need to insert each image of each record in the corresponding cell.
Currently I have a code that only inserts the last image it collects and repeats it throughout the column.
Here I leave my code:
Public Sub ExtraerImagenRegistrosDaño()
Dim img As Image
Dim imagecol As New DataGridViewImageColumn
imagecol.ImageLayout = DataGridViewImageCellLayout.Zoom
FormPrincipal.dgvRevisiones.Columns.Insert(0, imagecol)
Dim rutaTmp = Application.StartupPath & "/tmp"
If (Not System.IO.Directory.Exists(rutaTmp)) Then
System.IO.Directory.CreateDirectory(rutaTmp)
End If
For rowIndex = 0 To FormPrincipal.dgvRevisiones.RowCount - 1
Dim idreg = FormPrincipal.dgvRevisiones.Rows(rowIndex).Cells("idreg").Value.ToString
Dim descripcion = FormPrincipal.dgvRevisiones.Rows(rowIndex).Cells("descripcion").Value.ToString
ConexionBD.conectar()
Dim recoleccionidins As New DataTable
comandoquery = "SELECT idins FROM registro_dano WHERE descripcion='" & descripcion & "' AND idreg='" & idreg & "'"
comando.Connection = ConexionBD.conexion
comando.CommandText = comandoquery
recoleccionidins.Load(comando.ExecuteReader)
Dim idinsExtraido = recoleccionidins.Rows(0).Item(0).ToString().Trim()
ConexionBD.cerrar()
Dim sessionOptions As New SessionOptions
With sessionOptions
.Protocol = Protocol.Sftp
.HostName = "HOST"
.UserName = "USER"
.Password = "PASSWORD"
.GiveUpSecurityAndAcceptAnySshHostKey = True
End With
Using session As New Session
session.Open(sessionOptions)
Try
session.GetFiles("/home/sislota/database-registros-dano/Registro-" & idinsExtraido & "-" & idreg & ".png", rutaTmp & "\Registro-" & idinsExtraido & "-" & idreg & ".png").Check()
Catch ex As Exception
End Try
End Using
And here start the issue:
Try
img = Image.FromFile(rutaTmp & "\Registro-" & idinsExtraido & "-" & idreg & ".png")
Catch ex As Exception
End Try
imagecol.Image = img
Next
End Sub

vb.net Task.Factory multiple tasks needed?

Is this asynchronous programming correct ?
Since this is my first time using TAP, I want to make sure I do it correctly from the beginning.
I want to fill a table from a ODBC database and afterwards read some files and extract values out of it, without freezing my UI.
Why do I need to run OdbcDataAdapter and the file reading as tasks if I run the whole Function as a task in my UI Sub ? Otherwise it blocks my UI. thread.
UI Code
Private Async Sub frmOfsList_Shown(sender As Object, e As EventArgs) Handles MyBase.Show
Dim sw As New Stopwatch 'query time
sw.Start()
DataGridView1.Visible = False
Label2.Visible = False
DataGridView1.DataSource = Await OFS.GetJobList 'async method
sw.Stop()
Label2.Text = "Query time: " & sw.Elapsed.TotalSeconds & "s"
For i As Integer = 0 To DataGridView1.Rows.Count - 1 'color days until prodution date
If DataGridView1.Rows(i).Cells(3).Value < 0 Then
DataGridView1.Rows(i).Cells(3).Style.ForeColor = Color.Red
Else
DataGridView1.Rows(i).Cells(3).Style.ForeColor = Color.Green
End If
Next
DataGridView1.Visible = True 'show grid
DataGridView1.ClearSelection()
Label2.Visible = True
End Sub
Async Function
Public Shared Async Function GetJobList() As Task(Of DataTable)
Dim dq As Char = """"
Dim con As OdbcConnection = New OdbcConnection(constr)
con.Open()
'get data from OFS
Dim cmd As String = "SELECT p1.ProductionOrder, p1.Project, p1.ProductionDate, p1.Item, p1.Revision, p1.PlannedQty FROM " &
dq & "OFS460" & dq & "." & dq & "dbo" & dq & "." & dq & "tblProductionOrders" & dq & " p INNER JOIN " & dq & "OFS460" & dq & "." & dq & "dbo" &
dq & "." & dq & "tblProductionOrders" & dq & " p1 ON p.ProductionOrder = p1.ProductionOrder WHERE (p.Task=2820 AND p.StatusID=4) AND (p1.Task=2830 AND (p1.StatusID=1 OR p1.StatusID=2 OR p1.StatusID=3)) ORDER BY p1.ProductionDate"
Dim adapter As OdbcDataAdapter = New OdbcDataAdapter(cmd, con)
Dim datatable As New DataTable("JobList")
'fil table with job data async
Await Task.Factory.StartNew(Sub()
adapter.Fill(datatable)
End Sub)
'add columns to table
datatable.Columns.Add("Length", GetType(Double))
datatable.Columns.Add("Outside Dia", GetType(Double))
Dim proddate As DateTime
datatable.Columns.Add("Days until").SetOrdinal(3)
'calculate days
For j As Integer = 0 To datatable.Rows.Count - 1
proddate = datatable(j)(2)
datatable.Rows(j)(3) = proddate.Subtract(DateTime.Now).Days
Next
'Get length and diameter for each part
Dim searchpath As String = My.Settings.g250path
Await Task.Factory.StartNew(Sub()
Dim files As String()
Dim filetext As String
For i As Integer = 0 To datatable.Rows.Count - 1
files = System.IO.Directory.GetFiles(searchpath, "*" & datatable.Rows(i)("Item") & "*") 'get file by item#
If files.Length > 0 Then
filetext = System.IO.File.ReadAllText(files(0)) 'read file
datatable.Rows(i)("Length") = ProgramManager.GetValue(filetext, "I_R872", 7).ToString 'extract values
datatable.Rows(i)("Outside Dia") = ProgramManager.GetValue(filetext, "I_R877", 7).ToString
End If
Next i
End Sub)
Return datatable
End Function
You should not use Task.Factory.StartNew with Async-Await. You should use Task.Run, instead.
And you only need to get out of the UI thread once for the "heavy work" and return when done.
Try this:
Public Shared Function GetJobList() As DataTable
Dim dq As Char = """"
Dim con As OdbcConnection = New OdbcConnection(constr)
con.Open()
'get data from OFS
Dim cmd As String = "SELECT p1.ProductionOrder, p1.Project, p1.ProductionDate, p1.Item, p1.Revision, p1.PlannedQty FROM ""OFS460"".""dbo"".""tblProductionOrders"" p INNER JOIN ""OFS460"".""dbo"".""tblProductionOrders"" p1 ON p.ProductionOrder = p1.ProductionOrder WHERE (p.Task=2820 AND p.StatusID=4) AND (p1.Task=2830 AND (p1.StatusID=1 OR p1.StatusID=2 OR p1.StatusID=3)) ORDER BY p1.ProductionDate"
Dim adapter As OdbcDataAdapter = New OdbcDataAdapter(cmd, con)
Dim datatable As New DataTable("JobList")
'fil table with job data async
adapter.Fill(datatable)
'add columns to table
datatable.Columns.Add("Length", GetType(Double))
datatable.Columns.Add("Outside Dia", GetType(Double))
Dim proddate As DateTime
datatable.Columns.Add("Days until").SetOrdinal(3)
'calculate days
For j As Integer = 0 To datatable.Rows.Count - 1
proddate = datatable(j)(2)
datatable.Rows(j)(3) = proddate.Subtract(DateTime.Now).Days
Next
'Get length and diameter for each part
Dim searchpath As String = My.Settings.g250path
Dim files As String()
Dim filetext As String
For i As Integer = 0 To datatable.Rows.Count - 1
files = System.IO.Directory.GetFiles(searchpath, "*" & datatable.Rows(i)("Item") & "*") 'get file by item#
If files.Length > 0 Then
filetext = System.IO.File.ReadAllText(files(0)) 'read file
datatable.Rows(i)("Length") = ProgramManager.GetValue(filetext, "I_R872", 7).ToString 'extract values
datatable.Rows(i)("Outside Dia") = ProgramManager.GetValue(filetext, "I_R877", 7).ToString
End If
Next i
Return datatable
End Function
And invoke it like this:
DataGridView1.DataSource = Await Task.Run(AddressOf OFS.GetJobList1)
This way, the OFS.GetJobList1 function will be scheduled to execute on a thread pool thread and, when completed, the execution will resume on the caller sub/function and the return value of Task.Run (which is the return value of OFS.GetJobList1 wrapped with a Task(Of DataTable)) will be unwrapped and assigned to DataGridView1.DataSource.

Visual Basic InputBox closing error

This is a bit of a weird question, and apologies for the vast amount of code the question contains, but, I've been given somebody else's project to maintain, and the user has come to me with an error. There is a button which opens the InputBox, seen below.
The form is used to enter a path of a file to import. If the user enters no path, or an incorrect one, an error is displayed - fine. Now, the problem is, is that if the user presses the 'Cancel' button or the x in the top right to close the form, it also returns the same error, saying that the path cannot be found.
After looking through the following code, I can't work out how to make it so that the error is not displayed when pressing the x or Cancel, so can anybody help me out at all?
Private Sub btnImport_Click(sender As Object, e As EventArgs) Handles btnImport.Click
Try
Dim importbox As String = InputBox("Input path", "Import", "")
Dim fi As New FileInfo(importbox)
Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Text;Data Source=" & fi.DirectoryName
Dim conn As New OleDbConnection(connectionString)
conn.Open()
Dim add1 As String = ""
Dim add2 As String = ""
Dim add3 As String = ""
Dim add4 As String = ""
Dim add5 As String = ""
Dim postcode As String = ""
Dim telephone As String = ""
Dim fax As String = ""
Dim email As String = ""
Dim customercode As String = ""
Dim customername As String = ""
Dim webpage As String = ""
Dim mobile As String = ""
Dim headerTable As DataTable = ugHeaders.DataSource
Dim csvArray(headerTable.Rows.Count) As String
Dim i As Integer = 0
For Each dr As DataRow In headerTable.Rows
csvArray(i) = dr.Item("CSVName")
Next
For Each dr As DataRow In headerTable.Rows
Select Case dr.Item("DBName").ToString.Trim
Case "Add1"
add1 = dr.Item("CSVName")
Case "Add2"
add2 = dr.Item("CSVName")
Case "Add3"
add3 = dr.Item("CSVName")
Case "Add4"
add4 = dr.Item("CSVName")
Case "Add5"
add5 = dr.Item("CSVName")
Case "PostCode"
postcode = dr.Item("CSVName")
Case "Telephone"
telephone = dr.Item("CSVName")
Case "Fax"
fax = dr.Item("CSVName")
Case "Email"
email = dr.Item("CSVName")
Case "Customer_Name"
customername = dr.Item("CSVName")
Case "Customer_Code"
customercode = dr.Item("CSVName")
Case "webpage"
webpage = dr.Item("CSVName")
Case "mobile_phone"
mobile = dr.Item("CSVName")
End Select
Next
Dim sqlSelect As String = "SELECT Company, [" & add1 & "], [" & add3 & "], [" & postcode & "], [" & add2 & "], " & _
"[" & telephone & "], [" & fax & "], [" & email & "], [" & customercode & "], " & _
"[" & add4 & "], [" & add5 & "], [" & webpage & "], [" & mobile & "] FROM " & fi.Name
Dim cmdSelect As New OleDbCommand(sqlSelect, conn)
Dim adapter1 As New OleDbDataAdapter(cmdSelect)
Dim ds As New DataSet
adapter1.Fill(ds, "DATA")
pb_progress.Maximum = ds.Tables(0).Rows.Count
pb_progress.Value = 0
For Each dr As DataRow In ds.Tables(0).Rows
Try
Debug.WriteLine(dr.Item(customercode).ToString.Trim)
If dr.Item(customercode).ToString.Trim = "" Then
Dim str As String = dr.Item(customername)
If str.Trim = "" Then Continue For
Dim length As Integer = str.Length
If length < 20 Then
Else
length = 20
End If
str = Replace(str.Substring(0, length), " ", "_").ToUpper
str = Regex.Replace(str, "[^a-zA-Z _&]", "")
Dim found As Boolean = True
Dim loopcount As Integer = 1
Do Until found = False
Dim checkSql As String = "SELECT * FROM Customers WHERE [Customer_Code] = #ccode"
Dim checkCmd As New OleDb.OleDbCommand(checkSql, con)
checkCmd.Parameters.AddWithValue("#ccode", str)
Dim checkDa As New OleDb.OleDbDataAdapter(checkCmd)
Dim checkDt As New DataTable
checkDa.Fill(checkDt)
If checkDt.Rows.Count <> 0 Then
found = True
str &= CStr(loopcount)
loopcount += 1
Else
found = False
End If
Loop
dr.Item(customercode) = str
Else
Dim found As Boolean = True
Dim loopcount As Integer = 1
Do Until found = False
Dim checkSql As String = "SELECT * FROM Customers WHERE [Customer_Code] = #ccode"
Dim checkCmd As New OleDb.OleDbCommand(checkSql, con)
checkCmd.Parameters.AddWithValue("#ccode", dr.Item(customercode))
Dim checkDa As New OleDb.OleDbDataAdapter(checkCmd)
Dim checkDt As New DataTable
checkDa.Fill(checkDt)
If checkDt.Rows.Count <> 0 Then
found = True
dr.Item(customercode) &= CStr(loopcount)
loopcount += 1
Else
found = False
End If
Loop
End If
Dim sql As String
sql = "INSERT INTO Customers(Customer_Code, Customer_Name, Contract_Payment_Terms, Aq_Date, Telephone, Fax, Email, Average_Payment_Terms, webpage, mobile_phone) " & _
"VALUES(#ccode, #cname, 30, #01/01/2016#, #ctele, #cfax, #email, 30, #webpage, #mobile);"
Dim cmd As New OleDb.OleDbCommand(sql, con)
With cmd.Parameters
.AddWithValue("#ccode", dr.Item(customercode))
.AddWithValue("#cname", dr.Item(customername))
.AddWithValue("#ctele", dr.Item(telephone).ToString.Truncate(48))
.AddWithValue("#cfax", dr.Item(fax))
.AddWithValue("#email", dr.Item(email))
.AddWithValue("#webpage", dr.Item(webpage))
.AddWithValue("#mobile", dr.Item(mobile))
End With
cmd.ExecuteNonQuery()
sql = "INSERT INTO [Customer_Addresses] (Cust_Code, PostCode, Alias, Add1, Add2, Add3, Add4, Add5) VALUES(#ccode, #pcode, 'Default'" & _
",#add1, #add2, #add3, #add4, #add5);"
cmd = New OleDb.OleDbCommand(sql, con)
With cmd.Parameters
.AddWithValue("#ccode", dr.Item(customercode))
.AddWithValue("#pcdoe", dr.Item(postcode))
.AddWithValue("#add1", dr.Item(add1))
.AddWithValue("#add2", dr.Item(add2))
.AddWithValue("#add3", dr.Item(add3))
.AddWithValue("#add4", dr.Item(add4))
.AddWithValue("#add5", dr.Item(add5))
End With
cmd.ExecuteNonQuery()
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
pb_progress.Increment(1)
Next
MsgBox("Import successful", MsgBoxStyle.OkOnly, "Success")
Catch ex As Exception
errorLog(ex)
End Try
End Sub
Inputbox will always return a String.
If the Users presses "OK" it will return the String put into the TextBox.
If he cancels the box by pressing X or Cancel it returns "".
I would generally not recommend using an Inputbox for getting a filepath. Use an OpenFileDialog instead. If you have the fullpath already in your Clipboard you can just paste it into the Filename-Textboxof the OFD and press enter.
This should get you started:
Dim ofd as new OpenFileDialog()
// Show the File Dialog to the user and detect he pressed OK or Cancelled
if ofd.ShowDialog = Windows.Forms.DialogResult.OK
// Always check, if the file really exists
if IO.File.exists(ofd.FileName)
importbox = ofd.FileName
Else
msgbox("File does not exist")
Exit Sub
End if
Else
Exit Sub
End if

SELECT Query WHERE multiple values from checkboxlist are used

I was wondering if it was possible to filter down data from a table using multiple values from a checkboxlist? (or any other way) I have a checkboxlist and a gridview and when you check on of the boxes it does show the right data in the gridview but the problem arises when I try to check multiple values. It seems to search for the first checked value and then ignores the rest. You'd think it'd be simple! Perhaps it is. Here is my attempt below.
CODE BEHIND
Imports System.Data
Imports System.Data.SqlClient
Partial Class Default2
Inherits System.Web.UI.Page
Dim strSQL As New System.Text.StringBuilder
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then
Dim i As Integer, c As Integer = 0
Dim strParams As String = ""
For i = 0 To Me.CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
c += 1
If c = 1 Then
strParams = "(Keyword.Keyword = '" & CheckBoxList1.Items(i).Text & "')"
Else
strParams &= " AND (Keyword.Keyword = '" & CheckBoxList1.Items(i).Text & "')"
End If
End If
Next
strSQL.Append("SELECT Project.*")
strSQL.Append(" FROM Keyword INNER JOIN Project ON Keyword.ProjID = Project.ProjID")
strSQL.Append(" WHERE" & strParams)
FillGridView()
End If
End Sub
Private Sub FillGridView()
Dim strMyConn As String = "Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\FYPMS_DB.mdf;Integrated Security=True"
Using MyConn As New SqlClient.SqlConnection(strMyConn)
MyConn.Open()
Dim cmd As New SqlClient.SqlCommand(strSQL.ToString, MyConn)
cmd.Connection = MyConn
cmd.CommandType = CommandType.Text
Try
Using dr As SqlClient.SqlDataReader = cmd.ExecuteReader
Dim dt As New DataTable
dt.Load(dr)
Me.GridView1.DataSource = dt
Me.GridView1.DataBind()
End Using
If Me.GridView1.Visible = False Then Me.GridView1.Visible = True
Catch ex As Exception
Me.GridView1.Visible = False
End Try
End Using
End Sub
Protected Sub CheckBoxList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim i As Integer, c As Integer = 0
Dim strParams As String = ""
For i = 0 To Me.CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
c += 1
If c = 1 Then
strParams = "(Keyword.Keyword = '" & CheckBoxList1.Items(i).Text & "')"
Else
strParams &= " AND (Keyword.Keyword = '" & CheckBoxList1.Items(i).Text & "')"
End If
End If
Next
If c <> 0 Then
strSQL.Append("SELECT Project.*")
strSQL.Append(" FROM Keyword INNER JOIN Project ON Keyword.ProjID = Project.ProjID")
strSQL.Append(" WHERE" & strParams)
End If
End Sub
End Class
Refactor this section to create a WHERE IN statement so it checks to see if the value is found among any item checked
Before
Dim strParams As String = ""
For i = 0 To Me.CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
c += 1
If c = 1 Then
strParams = "(Keyword.Keyword = '" & CheckBoxList1.Items(i).Text & "')"
Else
strParams &= " AND (Keyword.Keyword = '" & CheckBoxList1.Items(i).Text & "')"
End If
End If
Next
After
Dim params As StringBuilder = New StringBuilder()
For i = 0 To Me.CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
params.Append("'")
params.Append(CheckBoxList1.Items(i).Text)
If i < Me.CheckBoxList1.Items.Count Then
params.Append("',") // don't append a comma if it's the last item
End If
End If
Next
strSQL.Append("SELECT Project.* FROM Keyword INNER JOIN Project ON Keyword.ProjID = Project.ProjID WHERE Keyword.Keyword in (")
strSQL.Append(params.ToString()) // append comma delimited values that make up where in statement
strSQL.Append("')") // close where in statement
FillGridView()

VB.net lag across different machines

I wrote a small little key inventory program. Basically it uses an INI file to know what keys we have and which ones are signed out, to whom, by whom, etc. It is run on up to 4 computers all in the same room and accesses the ini file on our local server.
When I sign a key out or in, it shows the change instantly. If I run two instances of the same program on the same machine, again, it's instant.
When I sign out a key on machine A and a co-worker is running the same program on machine B, C or D, the change in what is signed out doesn't show up for 4-10 seconds.
The way the program checks for updates is by using IO.File.Getlastwritetime on loading (saving it to a label with visible = false) and then every time the timer goes (every second) it compares the files "getlastwritetime" to the label. If they are different, then it updates, if they are the same, it does nothing.
Any idea where I should start looking for this lag? Could it be a server problem?
Here is the code for Timer1.tick, I am using the read/write ini codes from http://deepvbnet.blogspot.in/2008/07/how-to-read-from-ini-file.html
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim TimeCheck As String = IO.File.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/keys.ini")
If TimeCheck <> Label5.Text Then
ListBox1.Items.Clear()
ComboBox1.Items.Clear()
str1 = "NumOfKeys"
Call readIniFile()
Dim OneTime As String = strdata.ToString
Dim numberofkeys As Integer = Convert.ToInt32(OneTime)
For i = 1 To numberofkeys
str1 = "Key" & i & "Out"
Call readIniFile()
Dim isKeyOut As String = strdata.ToString
If isKeyOut = "True" Then
str1 = "Key" & i & "Name"
Call readIniFile()
Dim KeyName As String = strdata.ToString
str1 = "Key" & i & "Unit"
Call readIniFile()
Dim string1 As String = strdata.ToString
str1 = "Key" & i & "Rent"
Call readIniFile()
Dim string2 As String = strdata.ToString
str1 = "Key" & i & "User"
Call readIniFile()
Dim string3 As String = strdata.ToString
str1 = "Key" & i & "Date"
Call readIniFile()
Dim string4 As String = strdata.ToString
str1 = "Key" & i & "Time"
Call readIniFile()
Dim string5 As String = strdata.ToString
ListBox1.Items.Add(LSet(KeyName, 20) + " - " + string1 + " - " + string2 + " - " + string3 + " - " + string4 + " - " + string5)
ElseIf isKeyOut = "False" Then
str1 = "Key" & i & "Name"
Call readIniFile()
Dim thisKeysName As String = strdata.ToString
ComboBox1.Items.Add(thisKeysName)
End If
Next
Dim FileTime As String = IO.File.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/keys.ini")
Label5.Text = FileTime
End If
Dim escortTime As String = IO.Directory.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/Escort")
If escortTime <> Label7.Text Then
ListBox2.Items.Clear()
For Each foundfile In My.Computer.FileSystem.GetFiles("G:/BFAS/DPS/Comm Center/TEST/Escort/")
If foundfile = "G:/BFAS/DPS/Comm Center/TEST/Escorthistory.txt" Then
'do nothing
Else
Dim Infomation As String = My.Computer.FileSystem.ReadAllText(foundfile)
ListBox2.Items.Add(Infomation)
End If
Next
Label7.Text = IO.Directory.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/Escort")
End If
Dim alarmtime As String = IO.Directory.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/Alarms")
If alarmtime <> Label8.Text Then
ListBox3.Items.Clear()
For Each foundfile In My.Computer.FileSystem.GetFiles("G:/BFAS/DPS/Comm Center/TEST/Alarms/")
Dim Infomation As String = My.Computer.FileSystem.ReadAllText(foundfile)
ListBox3.Items.Add(Infomation)
Next
Label8.Text = IO.Directory.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/Alarms")
End If
Dim turnovertime As String = IO.File.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/turnover.txt")
If Label9.Text <> turnovertime Then
Dim newTO As String = My.Computer.FileSystem.ReadAllText("G:/BFAS/DPS/Comm Center/TEST/turnover.txt")
TextBox3.Text = newTO
Label9.Text = IO.File.GetLastWriteTime("G:/BFAS/DPS/Comm Center/TEST/turnover.txt")
End If
End Sub