VB6 to VB.NET conversion (Syntax : Print to StreamWriter/Reader)? [closed] - vb.net

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 1 year ago.
Improve this question
The following code is a part of VB6 application & I'm currently converting to VB.NET Windows Service. Line starts with Open gives me an error(I assume the 'Open' syntax does not support with VB.NET). I tried converting the code utilizing all the VB.NET knowledge I have but would like to know the ideal/optimistic solution.
VB6 Code
Private Sub Text1_GotFocus()
Me.lblCompanyName.Caption = ""
Me.lblCompanyName.Refresh
lngPosted = 0
lngSkipped = 0
lngClosed = 0
strMsg = Dir(strPath & "\WisysDataCollector_*.log", vbNormal)
Do While strMsg <> ""
On Error Resume Next
If strMsg < "WisysDataCollector_" & Format(DateAdd("m", -12, Now), "yyyyMM") Then
Kill(strPath & "\" & strMsg)
End If
On Error GoTo 0
strMsg = Dir()
Loop
datTimeStart = Now
Do
On Error Resume Next
Open strPath & "\WisysDataCollector_" & Format(Now, "yyyyMM") & ".log" For Append Lock Read Write As #1
lngST = Err.Number
strMsg = Err.Description
On Error GoTo 0
If lngST = 0 Then
Exit Do
End If
dblTimeElapsed = (Now - datTimeStart) * 24 * 60 * 60
If dblTimeElapsed > 20 Then
varResponse = vbCancel
If varResponse = vbCancel Then
strStatus = "Log file busy. Process aborted."
GoTo EXITFORM
End If
datTimeStart = Now
End If
Loop
Code continues.......
What I've tried : Created a 'FileIO' class as following with IO.StreamWriter and IO.StreamReader
Public Class FileIO
Public Shared Sub WriteLog(strToWrite As String)
Dim filePath As String = AppDomain.CurrentDomain.BaseDirectory + "\WisysDataCollector_" + Format(Now, "MMddyy") + ".log"
Dim streamWr As IO.StreamWriter = Nothing
Try
streamWr = New IO.StreamWriter(filePath, True)
streamWr.Write(Now + " - " + strToWrite + vbNewLine)
streamWr.Flush()
streamWr.Close()
Catch ex As Exception
End Try
End Sub
Public Shared Sub ReadLog(strToWrite As String)
Dim filePath As String = AppDomain.CurrentDomain.BaseDirectory + "\WisysDataCollector_" + Format(Now, "MMddyy") + ".log"
Dim streamRd As IO.StreamReader = Nothing
Try
streamRd = New IO.StreamReader(filePath, True)
streamRd.Read()
streamRd.Close()
Catch ex As Exception
End Try
End Sub
End Class
Please let me know the errors I've made in the above code also how should I use the 'FileIO' class to correct the errors with 'Open' and 'Print #1'?
Also if someone can please clarify what were they trying to do by this code line(honestly I'm trying to understand but not sure why they've multiplied the time difference by 24 * 60 * 60) dblTimeElapsed = (Now - datTimeStart) * 24 * 60 * 60?

The ampersand, &, is the concatenation character for vb.net. Although the plus sign will usually work, if numbers are involved you could get unexpected results.
Streams must be disposed to released unmanaged resources. Using...End Using blocks take care of this for us.
I made filePath a class level variable because it is used in more than one method. This must also be Shared because it is used in Shared methods. I changed the format of date so it will appear chronologically in File Explorer.
It makes no sense to read the log and do nothing with it. I changed the ReadLog method to a Function. It also makes no sense to pass a string to it.
I believe the vb6 code was trying to express elapsed time in seconds with the 24 60 60 business. I gave you an example of that with the Form.Load setting the startTime and then hitting a button some time later and calculating the seconds that had passed.
In the form class...
Private StartTime As DateTime
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
StartTime = Now
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
FileIO.WriteLog(TextBox1.Text)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox2.Text = FileIO.ReadLog
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim elapsedTime As TimeSpan = Now - StartTime
Dim TotalSeconds = elapsedTime.TotalSeconds
MessageBox.Show($"The elapsed time since the program started is {TotalSeconds}")
End Sub
Your class would look like this...
Public Class FileIO
Private Shared filePath As String = AppDomain.CurrentDomain.BaseDirectory & "\WisysDataCollector_" & Format(Now, "yyyyMMdd") & ".log"
Public Shared Sub WriteLog(strToWrite As String)
Using sw = File.AppendText(filePath)
sw.WriteLine(strToWrite)
End Using
End Sub
Public Shared Function ReadLog() As String
If File.Exists(filePath) Then
Return File.ReadAllText(filePath)
Else
Return ""
End If
End Function
End Class

Related

VB.NET runs differently when message box removed - Outlook Application

I'm currently developing an Outlook Application, which seemed to work perfectly during testing.
This code seems to work when the MSGBox("ASDFG") is in place (rsts.Count returns 1), but as soon as it is removed, the statement returns 0. I have tried to surpass this by adding Debug.Print's to see if that made any difference, but I still find that the code will only run correctly when the MSGBox is in place.
I even added a Timer1 interval to re-run the script every second if it returns 0.
Function myThread()
Dim oApp As Outlook.Application = CreateObject("Outlook.application")
Dim sch As Outlook.Search
Dim rsts As Outlook.Results
Dim i As Integer
Dim myTaskSearch As String = ToolStripStatusLabel2.Text
Dim strF As String = "urn:schemas:mailheader:subject LIKE '%Task: " & myTaskSearch & "%'"
Const strS As String = "Inbox"
Try
sch = oApp.AdvancedSearch(strS, strF)
rsts = sch.Results
MsgBox("ASDFG")
Debug.Print(sch.Results.ToString)
Debug.Print("'" & myTaskSearch & "'")
If rsts.Count = 0 Then
Debug.Print(rsts.Count)
Timer1.Interval = 1000
Timer1.Start()
End If
For i = 1 To rsts.Count
Debug.Print(i)
Timer1.Stop()
TabControl1.TabPages.Add(i)
'rsts.Item(i).Body
'rsts.Item(i).SenderName
Next
Catch ex As System.Exception
MsgBox(ex.ToString)
End Try
End Function
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
myThread()
End Sub
With MSGBox
Without MSGBox + Debug
Add an event handler to be called when the search is complete. As GSerg said, AdvancedSearch is asynchronous so it is still running when your code prints the count.
See the documentation for a code example.

VB.Net Webclient Upload Hanging

I have multiple files to upload (to FTP server) using this code:
Private Sub UploadFile(ByVal local As String)
If wc.IsBusy = True Then Throw New Exception("An upload is already ongoing!")
wc.Credentials = New NetworkCredential(usr.ToString, pass.ToString) 'Set the credentials.
'total_dl_size = GetDownloadSize(url) 'Get the size of the current file.
Try
Dim FileName As String = Path.GetFileName(local) 'Get the current file's name.
AppendWarning("Uploading " & FileName & "... ") 'Download notice.
wc.UploadFileAsync(New Uri(info_srv & local), Path.Combine(mc_dir, local)) 'Download the file to the desktop (use your own path here).
Catch ex As Exception
AppendWarning("-ERR: Could not download file: " & local & ControlChars.NewLine)
End Try
End Sub
Private Sub AppendWarning(ByVal Text As String)
If tb_warnings.InvokeRequired Then
tb_warnings.Invoke(Sub() tb_warnings.AppendText(Text))
Else
tb_warnings.AppendText(Text)
End If
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As System.Net.UploadProgressChangedEventArgs) Handles wc.UploadProgressChanged
total_ul = e.BytesSent
Dim Progress As Integer = CType(Math.Round((baseline + total_ul) * 100) / total_ul_size, Integer)
If ProgressBar1.InvokeRequired Then
ProgressBar1.Invoke(Sub()
If Progress > 100 Then Progress = 100
If Progress < 0 Then Progress = 0
ProgressBar1.Value = Progress
End Sub)
Else
If Progress > 100 Then Progress = 100
If Progress < 0 Then Progress = 0
ProgressBar1.Value = Progress
End If
If lbl_progress.InvokeRequired Then
lbl_progress.Invoke(Sub() lbl_progress.Text = ((total_ul + baseline) / 1024).ToString("N0") & " KB / " & (total_ul_size / 1024).ToString("N0") & " KB")
Else
lbl_progress.Text = ((total_ul + baseline) / 1024).ToString("N0") & " KB / " & (total_ul_size / 1024).ToString("N0") & " KB | " & Progress.ToString & "%"
End If
End Sub
Private Sub wc_uploadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.UploadDataCompleted
If e.Cancelled Then
MessageBox.Show(e.Cancelled)
ElseIf Not e.Error Is Nothing Then
MessageBox.Show(e.Error.Message)
Else
If files.Count > 0 Then
AppendWarning("Upload Complete!" & ControlChars.NewLine)
baseline = baseline + total_ul
Dim file As String = files.Dequeue()
MsgBox(file)
UploadFile(file) 'Download the next file.
Else
AppendWarning("All Uploads Finished!" & ControlChars.NewLine)
End If
End If
However, using my two test files, it always stops at what would otherwise be the end of the first file I've given it, and doesn't go onto the second one.
However, I have an FTP client connected to this same server, and when I refresh I can see (at least for the first file) the data is being properly uploaded.
Any suggestions as to what's going wrong here?
Edit, log: http://pastebin.com/kqG28NGH
Thank you for any assistance!
This works for me...I tried to mimic what I think is in your form. I tested with a queue of 8 files ranging from 150K to 400K each. I couldn't quite work out what you were trying to do with the progress bar. Mine fills for each file and resets for the next, finishing empty with the last call to DoUpload where there are no more files. Hopefully, this will help.
Imports System.IO
Imports System.Net
Public Class Form1
Const info_srv As String = "ftp://example.com/SomeFolder/"
Const usr As String = ""
Const pass As String = ""
Const mc_dir As String = "D:\Source\Folder"
Private WithEvents wc As New Net.WebClient
' Contains file names only, no paths
Private Files As New Queue(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) _
Handles Button1.Click
wc.Credentials = New NetworkCredential(usr, pass)
' Put the work in a task so UI is responsive
Task.Run(Sub() DoUpload())
End Sub
Private Sub DoUpload()
ShowProgress("", 0)
If Files.Count > 0 Then
Dim local As String = Files.Dequeue
Dim FileName As String = Path.Combine(mc_dir, local)
AppendWarning("Uploading " & FileName & "... ")
Try
wc.UploadFileAsync(New Uri(info_srv & local), FileName)
Catch ex As Exception
AppendWarning("-ERR: Could not upload file: " & local & Environment.NewLine)
End Try
Else
AppendWarning("All Uploads Finished!" & Environment.NewLine)
End If
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) _
Handles wc.UploadProgressChanged
' Do not use e.ProgressPercentage - it's inaccurate by half by design per Microsoft
With String.Format("{0} KB / {1} KB", Int(e.BytesSent / 1024).ToString("N0"), Int(e.TotalBytesToSend / 1024).ToString("N0"))
ShowProgress(.ToString, Int(e.BytesSent / e.TotalBytesToSend * 100))
End With
End Sub
Private Sub wc_UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) _
Handles wc.UploadFileCompleted
Select Case True
Case e.Cancelled
MessageBox.Show("Cancelled")
Case e.Error IsNot Nothing
MessageBox.Show(e.Error.Message)
Case Else
AppendWarning("Upload Complete!" & Environment.NewLine)
' I needed this just so I could see it work, otherwise too fast
Threading.Thread.Sleep(500)
DoUpload()
End Select
End Sub
Private Sub AppendWarning(ByVal Text As String)
If Me.InvokeRequired Then
Me.Invoke(Sub() AppendWarning(Text))
Else
tb_warnings.AppendText(Text)
End If
End Sub
Private Sub ShowProgress(LabelText As String, Progress As Integer)
If Me.InvokeRequired Then
Me.Invoke(Sub() ShowProgress(LabelText, Progress))
Else
Me.lbl_progress.Text = LabelText
Me.lbl_progress.Refresh()
Me.ProgressBar1.Value = Progress
Me.ProgressBar1.Refresh()
End If
End Sub
End Class
For posterity:
Check your network trace settings in the VB config. I used a really verbose catch-all config I found to do the trace, but it seems the overhead was killing the upload. I've since found a much leaner focus-on-ftp set of xml to modify this and the files now upload properly. Thank you everyone!

Calling a procedure from its non native form

Ok, so
frmResult populates a ListView with various calculations
frmMenu has an export button (see code below). Pressing this is supposed to export the data in the ListView to a txt file. Currently, this button does not work. It says, List View is undeclared - obviously because the code shown below is not 'seeing' data held in frmResult
Question – how do I call the procedures stored in frmResult so that frmMenu can 'see' it.
Public Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
Dim fileSaved As Boolean
Dim filePath As String
Do Until fileSaved
'Request filename from user
Dim saveFile As String = InputBox("Enter a file name to save this message")
'Click Cancel to exit saving the work
If saveFile = "" Then Exit Sub
'
Dim docs As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments
filePath = IO.Path.Combine(docs, "Visual Studio 2013\Projects", saveFile & ".txt")
fileSaved = True
If My.Computer.FileSystem.FileExists(filePath) Then
Dim msg As String = "File Already Exists. Do You Wish To Overwrite it?"
Dim style As MsgBoxStyle = MsgBoxStyle.YesNo Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Critical
fileSaved = (MsgBox(msg, style, "Warning") = MsgBoxResult.Yes)
End If
Loop
'the filePath String contains the path you want to save the file to.
Dim rtb As New RichTextBox
rtb.AppendText("Generation, Num Of Juveniles, Num of Adults, Num of Semiles, Total" & vbNewLine)
For Each saveitem As ListViewItem In ListView1.Items
rtb.AppendText(
saveitem.Text & ", " &
saveitem.SubItems(1).Text & ", " &
saveitem.SubItems(2).Text & ", " &
saveitem.SubItems(3).Text & ", " &
saveitem.SubItems(4).Text & vbNewLine)
Next
rtb.SaveFile(filePath, RichTextBoxStreamType.PlainText)
End Sub
Is this what you mean?
Public Sub Init()
'... (all the code)
End Sub
Private Sub Results_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call Init()
End Sub
You can call Init() from every form load you want. Maybe you want to create a module and store there your methods.
By the way, you only use Function when your methods needs to return a value.
If your code uses elements of the form (or other objects not constant) you need to pass those to the method, like this:
Public Sub Init(myListView As ListView)
myListView.Items.Add("something")
'...
End Sub
Private Sub Results_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call Init(ListView1)
End Sub
You can add as many parameters as you need. You have to learn the basics before going ant further.
This is a great piece of literature for those struggling with the basics like myself.
You can write code to access objects on a different form. However, you must fully identify the name of the object by preceding it with the object variable name.
Dim resultsForm As New frmResults
resultsForm.lblAverage.Text = sngAverage.ToString()
In these statements, for example, I have declared an object variable called resultsForm that is linked to the form frmResults. The second statement assigns the string value of sngAverage to the lblAverage label box on the frmResults form.
In my code, I needed to change the line that said:
For Each saveitem As ListViewItem In ListView1.Items
To this:
For Each saveitem As ListViewItem In Results.ListView1.Items
I also needed to make sure that the procedure on formResults was made Public not Private

vb.net update progress bar multithread

Long time reader, first time poster. Usually I'm able to find the answer and make it work. Not this time..... I'm using VB.NET in VS2013. I am trying to update a progress bar with work done in a secondary thread. Easy right? No. I had to make it more complicated. The progress bar (ToolStripProgressBar1) is on the main form (frmMain), the MDI of the project. A secondary form (frmShipping) has a button which initiates a second thread to do some COMM Port communications in a class (cApex). I can get the progress bar to update on the frmMain from the main UI thread (frmShipping button).
This is the code from button on frmShiping and the multithread procedure:
Private Sub btnreadScanner_Click(sender As Object, e As EventArgs) Handles btnreadScanner.Click
Dim thrReadScanner As New System.Threading.Thread(AddressOf ReadScanner)
thrReadScanner.IsBackground = True
thrReadScanner.Start()
End Sub
Private Sub ReadScanner()
Dim strRowCount As String
ShipmentMsg(2)
strRowCount = objShipping.RecordsExisit.ToString()
Try
objApex.ImmediateMode()
If objApex.FileDownload = False Then
Throw New Exception(Err.Description)
End If
Catch ex As Exception
ShipmentMsg(1)
MessageBox.Show("No Data downloaded from Scanner. Try Again. Error#: " & Err.Number & " : " & Err.Description)
Exit Sub
End Try
RecordCount()
DataGridUpdate()
btnProcessShipment.Enabled = True
ShipmentMsg(5)
ScanErrors()
End Sub
This all works great. As expected. The call to objApex.FileDownload in class cApex is where progress bar is to be updated from (actually in another function called from FileDownload). So here is the code there.
Try
GetHeaderRecord()
If Count <> 0 Then intTicks = Math.Round((100 / Count), 1)
For intcount As Integer = 1 To Count
Dim intLength As Integer = Length
Do While intLength > 0
literal = Chr(_serialPort.ReadChar.ToString)
If literal = ">" Then Exit Do
strRecord = strRecord & literal
intLength = intLength - 1
Loop
REF = strRecord.Substring(0, 16).TrimEnd
SKID = strRecord.Substring(16, 16).TrimEnd
REEL_BC = strRecord.Substring(32, 15).TrimEnd
ScanDate = strRecord.Substring(47, 8).TrimEnd
ScanDate = DateTime.ParseExact(ScanDate, "yyyyMMdd", Nothing).ToString("MM/dd/yyyy")
ScanTime = strRecord.Substring(55, 6).TrimEnd
ScanTime = DateTime.ParseExact(ScanTime, "HHmmss", Nothing).ToString("HH:mm:ss")
strRecordTotal = strRecordTotal & strRecord & CRLF
Dim strSQL As String
strSQL = "INSERT INTO tblScanData (PONo,Barcode,SkidNo,ScanDate,ScanTime) " & _
"VALUES (" & _
Chr(39) & REF & Chr(39) & _
"," & Chr(39) & REEL_BC & Chr(39) & _
"," & Chr(39) & SKID & Chr(39) & _
"," & Chr(39) & ScanDate & Chr(39) & _
"," & Chr(39) & ScanTime & Chr(39) & ")"
objData.Executecommand(strSQL)
strRecord = ""
Next
And finally this is how I was calling the progress bar update.
Dim f As frmMain = frmMain
System.Threading.Thread.Sleep(100)
DirectCast(f, frmMain).ToolStripProgressBar1.PerformStep()
I really need to put the PerformStep in the For loop. Each time around the loop will step the progress bar the percentage of steps needed to make bar fairly accurate (done by the math code before loop). Also I setup the properties of the progress bar control on frmMain. So, am I crazy, or is there a way to accomplish this? I tried using a delegate; Me.Invoke(New MethodInvoker(AddressOf pbStep)) to make code cross thread safe. I don't get an error about cross thread calls, but the progress bar doesn't update either. Sorry it's a long one but I'm lost and my ADHD won't let me scrap this idea.
EDIT AS REQUESTED:
Public Sub pbStep()
Dim f As frmMain = frmMain
If Me.InvokeRequired Then
Me.Invoke(New MethodInvoker(AddressOf pbStep))
Else
DirectCast(f, frmMain).ToolStripProgressBar1.PerformStep()
System.Threading.Thread.Sleep(100)
End If
End Sub
Both responses helped lead me to the correct answer I was needing. The code provided by James was a great starting point to build on, and Hans has several post explaining the BackgroundWorker. I wanted to share the "Answer" I came up with. I'm not saying its the best way to do this, and I'm sure I'm violating some rules of common logic. Also, a lot of the code came from a MSDN example and James's code.
Lets start with the form from which I am calling the bgw, frmShipping. I added this code:
Dim WithEvents bgw1 As New System.ComponentModel.BackgroundWorker
Private Sub bgw1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles bgw1.RunWorkerCompleted
If e.Error IsNot Nothing Then
MessageBox.Show("Error: " & e.Error.Message)
ElseIf e.Cancelled Then
MessageBox.Show("Process Canceled.")
Else
MessageBox.Show("Finished Process.")
End If
End Sub
Private Sub bgw1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
Handles bgw1.ProgressChanged
DirectCast(Me.MdiParent, frmMain).ToolStripProgressBar1.Maximum = 1960
DirectCast(Me.MdiParent, frmMain).ToolStripProgressBar1.Step = 2
Dim state As cApex.CurrentState =
CType(e.UserState, cApex.CurrentState)
DirectCast(Me.MdiParent, frmMain).txtCount.Text = state.LinesCounted.ToString
DirectCast(Me.MdiParent, frmMain).txtPercent.Text = e.ProgressPercentage.ToString
DirectCast(Me.MdiParent, frmMain).ToolStripProgressBar1.PerformStep()
End Sub
Private Sub bgw1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles bgw1.DoWork
Dim worker As System.ComponentModel.BackgroundWorker
worker = CType(sender, System.ComponentModel.BackgroundWorker)
Dim objApex As cApex = CType(e.Argument, cApex)
objApex.CountLines(worker, e)
End Sub
Sub StartThread()
Me.txtCount.Text = "0"
Dim objApex As New cApex
bgw1.WorkerReportsProgress = True
bgw1.RunWorkerAsync(objApex)
End Sub
Next I added the following code the my cApex class.
Public Class CurrentState
Public LinesCounted
End Class
Private LinesCounted As Integer = 0
Public Sub CountLines(ByVal worker As System.ComponentModel.BackgroundWorker, _
ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim state As New CurrentState
Dim line = ""
Dim elaspedTime = 20
Dim lastReportDateTime = Now
Dim lineCount = File.ReadAllLines(My.Settings.strGenFilePath).Length
Dim percent = Math.Round(100 / lineCount, 2)
Dim totaldone As Double = 2
Using myStream As New StreamReader(My.Settings.strGenFilePath)
Do While Not myStream.EndOfStream
If worker.CancellationPending Then
e.Cancel = True
Exit Do
Else
line = myStream.ReadLine
LinesCounted += 1
totaldone += percent
If Now > lastReportDateTime.AddMilliseconds(elaspedTime) Then
state.LinesCounted = LinesCounted
worker.ReportProgress(totaldone, state)
lastReportDateTime = Now
End If
System.Threading.Thread.Sleep(2)
End If
Loop
state.LinesCounted = LinesCounted
worker.ReportProgress(totaldone, state)
End Using
End Sub
I also added a couple of text boxes to my main form to show the current line count from the file being read from and the overall progress as a percentage of a 100. Then on the Click event of my button I just call StartThread(). It is not 100% accurate, but its close enough to give the user a very good idea where the process stands. I have a little more work to do to add it to the "ReadScanner" function, where I originally was wanting to use the progress bar. But this function it the longer of the two that I perform on the scanner, writing almost 2,000 lines of code through a COMM Port. I'm happy with the results.
Thank you guys for helping out!
P.S. I have also now added variables to set the pbar.Maximum and the pbar.step since those can change if the scanner file is changed.
Background workers are useful for this purpose. Just use it in combination with a delegate. All the threaded work is done within the DoWork event of the worker. As progress is made, progress is reported within the DoWork event. This in turn fires the ProgressedChanged event of the worker class which is on the same thread as the progressbar. Once the DoWork has completed and is out of scope, the RunWorkerCompleted event is fired. This can be used to do inform the user that the task is complete, etc. Here is a working solution that I threw together. Just paste it behind an empty form and run.
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Threading
Public Class Form1
Private _progressBar As ProgressBar
Private _worker As BackgroundWorker
Sub New()
' This call is required by the designer.
InitializeComponent()
Initialize()
BindComponent()
End Sub
Private Sub Initialize()
_progressBar = New ProgressBar()
_progressBar.Dock = DockStyle.Fill
_worker = New BackgroundWorker()
_worker.WorkerReportsProgress = True
_worker.WorkerSupportsCancellation = True
Me.Controls.Add(_progressBar)
End Sub
Private Sub BindComponent()
AddHandler _worker.ProgressChanged, AddressOf _worker_ProgressChanged
AddHandler _worker.RunWorkerCompleted, AddressOf _worker_RunWorkerCompleted
AddHandler _worker.DoWork, AddressOf _worker_DoWork
AddHandler Me.Load, AddressOf Form1_Load
End Sub
Private Sub Form1_Load()
_worker.RunWorkerAsync()
End Sub
Private Sub _worker_ProgressChanged(ByVal o As Object, ByVal e As ProgressChangedEventArgs)
_progressBar.Increment(e.ProgressPercentage)
End Sub
Private Sub _worker_RunWorkerCompleted(ByVal o As Object, ByVal e As RunWorkerCompletedEventArgs)
End Sub
Private Sub _worker_DoWork(ByVal o As Object, ByVal e As DoWorkEventArgs)
Dim worker = DirectCast(o, BackgroundWorker)
Dim value = 10000
SetProgressMaximum(value)
For x As Integer = 0 To value
Thread.Sleep(100)
worker.ReportProgress(x)
Next
End Sub
Private Sub SetProgressMaximum(ByVal max As Integer)
If _progressBar.InvokeRequired Then
_progressBar.Invoke(Sub() SetProgressMaximum(max))
Else
_progressBar.Maximum = max
End If
End Sub
End Class

VB.NET FileSystemWatcher - Copy created file [duplicate]

This question already has answers here:
Wait Until File Is Completely Written
(9 answers)
Closed 8 years ago.
^^^ That answer is in C#! I am using VB.NET! ^^^
I am using a FileSystemWatcher to monitor a folder for new files.
This sub gets triggered when it detects a change, which should then copy the file to the server.
Private Sub OnCreated(source As Object, e As FileSystemEventArgs)
Dim LocalFile As String = e.FullPath
Dim ServerFile As String = LocalFile.Replace(localSyncPath, serverSyncPath)
Try
File.Copy(LocalFile, ServerFile)
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
Problem is that this usually pops up an error to say the file is in use. Is there a way to run a loop to keep trying until it works? Or even copy dispite being in use?
The link I gave for you to examine is easily translated to VB.NET:
Public Shared Sub listener_Created(sender As Object, e As FileSystemEventArgs)
Console.WriteLine("File Created:" & vbLf + "ChangeType: " + e.ChangeType + vbLf & "Name: " + e.Name + vbLf & "FullPath: " + e.FullPath)
Try
File.Copy(e.FullPath, "D:\levani\FolderListenerTest\CopiedFilesFolder\" + e.Name)
Catch
_waitingForClose.Add(e.FullPath)
End Try
Console.Read()
End Sub
Public Shared Sub listener_Changed(sender As Object, e As FileSystemEventArgs)
If _waitingForClose.Contains(e.FullPath) Then
Try
File.Copy(...)
_waitingForClose.Remove(e.FullPath)
Catch
End Try
End If
End Sub