I have a windows form which has a download button. The download button creates another class' object and this object triggers the download. I have created a progress bar in the main windows form and want this progress bar to update as the file gets downloaded.
The main windows form calls the object as below :
Dim dwObj= Downloader()
dwObj.DownloadFileFromLocation(fileName, fileType)
The DownloadFileFromLocation method is defined as below in the Downloader class :
Public Function DownloadFileFromLocation(FileName As String, FileType As String))
Dim Address As String = "MyLINK"
If (Not System.IO.Directory.Exists(MyLocalPath)) Then
System.IO.Directory.CreateDirectory(MyLocalPath)
End If
Try
Dim fileReader As New WebClient()
If (FileType.Equals(MyFileType)) Then
If Not (System.IO.File.Exists(MyLocalPath + FileName)) Then
AddHandler fileReader.DownloadProgressChanged, AddressOf Download_ProgressChanged
fileReader.DownloadFile(Address, MyLocalPath + FileName)
End If
End If
If (FileType.Equals(AWSGlobals.DWC)) Then
If Not (System.IO.File.Exists(AWSGlobals.DWPath + FileName)) Then
fileReader.DownloadFile(Address, AWSGlobals.DWPath + FileName)
End If
End If
Catch ex As HttpListenerException
Console.WriteLine("Error accessing " + Address + " - " + ex.Message)
Catch ex As Exception
Console.WriteLine("Error accessing " + Address + " - " + ex.Message)
End Try
End Function
Now, I have defined a function to update the progress bar, but since its in another file, I get an error :
Private Sub Download_ProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
Try
ProgressBar1.Value = CInt(Math.Round((e.BytesReceived / e.TotalBytesToReceive) * 100, 0, MidpointRounding.AwayFromZero))
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
Now I get the error, which I understand because Progress bar is declared in the main windows form
ProgressBar1 is not declared. It may be inaccessible due to its protection level
The question is how can I handle this now. Can someone please help me out here?
Related
I leave it to you because I can't find a solution to my problem : /
Let me explain, when I press a button I display a panel containing other buttons, at the click of one of the buttons on the panel it should launch a method that will convert the selected files to pdf. As soon as the user has clicked on one of the buttons and confirmed the choice of file, I make my panel invisible and I then launch the conversion method.
The problem is that my panel disappears let's say by half (not entirely) because it launches the conversion method as quickly. I told myself that I was going to go through a secondary thread, however I cannot modify graphic elements on the second thread.
There is my code :
Private Sub PBFolder_Click(sender As Object, e As EventArgs) Handles PBFolder.Click
Try
Insert2Db("Debut de la fonction BTransforme_Click " + Environment.UserName.ToString, 1, 0, "ConvertFiles2PDF")
'Log("Debut de la fonction BTransforme_Click")
Dim OFD As New FolderBrowserDialog
If OFD.ShowDialog = Windows.Forms.DialogResult.OK Then
PanFileFolder.Visible = False
ConvertFileFolder(False, OFD.SelectedPath.ToString)
End If
Catch ex As Exception
'Log("Error " + ex.Message)
Insert2Db("Error " + ex.Message + "User : " + Environment.UserName.ToString, 0, 3, "ConvertFiles2PDF")
Finally
Insert2Db("function BTransforme_Click Terminé " + Environment.UserName.ToString, 1, 0, "ConvertFiles2PDF")
'Log("function BTransforme_Click Terminé")
End Try
LAppOne.Visible = True
GifLoad.Visible = False
Button1.Enabled = True
BLog.Enabled = True
End Sub
As you can see I hide my panel thanks to line: PanFileFolder.Visible = False then I launch my conversion method convertFileFolder (False, OFD.SelectedPath.ToString)
I have put 2 images to illustrate my problem.
the 1st image shows you the panel that appears on click:
the second image shows you the problem that this causes me to choose the folder:
When it has finished converting the files, the panel disappears correctly at this time.
Do you have an idea to solve this problem thank you in advance ;)
I told myself that I was going to go through a secondary thread,
however I cannot modify graphic elements on the second thread.
That is exactly what will fix your problem; ConvertFileFolder() needs to be running in a different thread so that GUI can refresh itself and be responsive to user interact. You can update the GUI from that secondary thread using Invoke() calls.
Here I've added Async to the Button click handler, then we Await the ConvertFileFolder() FUNCTION, which now returns a Task:
Private Async Sub PBFolder_Click(sender As Object, e As EventArgs) Handles PBFolder.Click
' ... other code ...
Using OFD As New FolderBrowserDialog
If OFD.ShowDialog = DialogResult.OK Then
PanFileFolder.Visible = False
Await ConvertFileFolder(False, OFD.SelectedPath.ToString)
End If
End Using
' ... other code ...
End Sub
Public Function ConvertFileFolder(ByVal someFlag As Boolean, ByVal someString As String) As Task
Return Task.Run(Sub()
' ... long running code in here ...
For i As Integer = 1 To 10
System.Threading.Thread.Sleep(1000) ' some "work"
' whenever you need to update the GUI, use Invoke()
Dim value As String = i.ToString
Me.Invoke(Sub()
Label1.Text = value
End Sub)
Next
End Sub)
End Function
I'm using a web page to create a file on a web server to control an Arduino device. The file gets created without issue. The problem exists when the VB app that controls the Arduino device reads the file and then deletes the file. After VB deletes the file the web app recreates the same file with new data. The VB app fails to see the new file. It still thinks the file has been deleted.
Here's the code:
Private Sub TimerCheck4CameraFile_Tick(sender As Object, e As EventArgs) Handles TimerCheck4CameraFile.Tick
Try
' Check if file exists if it doesn't leave this method.
Dim DirectoryList As New IO.DirectoryInfo("C:\inetpub\wwwroot")
Dim ArrayOfFilesFileInfo As IO.FileInfo() = DirectoryList.GetFiles("ServoDirection2Move.txt")
Dim Fi As IO.FileInfo
For Each Fi In ArrayOfFilesFileInfo
If String.Compare("ServoDirection2Move.txt", Fi.Name) <> 0 Then
TextBox1.Text += vbCrLf + "Did NOT Find File."
Exit Sub ' We DID NOT find the file so get out!
End If
Next
Catch ex As Exception
LabelStatus.Text = "Catch ex 1: " + ex.Message
End Try
' Read in the file.
Dim FileRead As String
Try
' **POSSIBLE ISSUE HERE**.
FileRead = My.Computer.FileSystem.ReadAllText("C:\inetpub\wwwroot\ServoDirection2Move.txt")
' Need better way to read txt file. It fails after file is deleted and can not read second file.
TextBox1.Text += vbCrLf + "Moving Value: " + FileRead
Catch ex As Exception
LabelStatus.Text = "Catch ex: " + ex.Message
End Try
' Check if it was UP.
If String.Compare("UP", FileRead) = 0 Then
' Delete the file to prepare for a new one.
System.IO.File.Delete("C:\inetpub\wwwroot\ServoDirection2Move.txt")
' Move servo to proper location.
Call PanningUp.PerformClick()
LabelStatus.Text = "Done Moving: UP" ' Update Status Bar.
TimerCheck4CameraFile.Enabled = True ' Turn timer back on.
Exit Sub
End If
Hi there I am carrying out some integration testing in an application I am developing. The specific element that is causing an issue is a call to a background worker which interrogates an Oracle database. When an error is encountered in the query I want the exception detail to percolate up the call stack to the application level and at that point provide an appropriate user compatible message. In the example test there is a syntax error in the underlying SQL which results in an OraEx Exception:
Oracle.DataAccess.Client.OracleException ORA-00907: missing right parenthesis
Unfortunately the code generates the following exception:
System.Reflection.TargetInvocationException was unhandled
Message: An unhandled exception of type
'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Additional information: Exception has been thrown by the target of an
invocation.
in the DoWork sub of the backgroundworker, despite my belief that I am handling the exception correctly. Its pretty obvious that I am missing something fundamental here, can someone suggest a solution please.
Thanks in Advance
Paul J.
Here is the code that makes the call to the background worker:
Private Sub EventSearch(ByVal mySQL As String)
Const procName As String = "EventSearch"
Try
_eventMngr = New ScadaEventManager(_CurrentDB, _userName, _myPwd)
_eventMngr.SQL = mySQL
'Set the flag and stop query tool status accordingly
_Stopped = False
uxStopQueryTool.Enabled = True
'activate the timer object to ensure that the execute query menu
'and tool remain disabled until all background processing is complete
uxBackWorkTimer.Enabled = True
_logger.SendLog(Me.Name & "." & procName & " - Scanning for data.", NLog.LogLevel.Trace)
ReviseStatus(2, "Scanning for data. Please wait...", Color.Black, True, True)
'Force the thread to sleep for half a second so the user can see the scanning state taking place
Threading.Thread.Sleep(500)
'Launch the background worker to retrieve the required data from the database
uxBWScan.RunWorkerAsync(_eventMngr)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, My.Application.Info.ProductName)
_logger.SendLog(ex.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, ex)
Call ResetStatus()
Finally
End Try
End Sub
And here is the code executed by the background worker:
Private Sub uxBWScan_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles uxBWScan.DoWork
Const procName As String = "uxBWScan_DoWork"
Try
e.Argument.CountRecords(_queryTypeID)
e.Result = e.Argument.RecordCount
Catch NullEx As NullReferenceException
_logger.SendLog(NullEx.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, NullEx)
Throw
Catch OraEx As OracleException
_logger.SendLog(OraEx.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, OraEx)
Throw
Finally
End Try
End Sub
And here is the low level code that generates the error:
Public Sub CountRecords(ByVal queryType As Integer)
_myDataset = New DataSet
Try
_myDataset = _myScadaEventDB.CountRecords(_sqlText)
If _myDataset.Tables(0).Rows.Count > 0 Then
If queryType = Enums.QueryType.General Or queryType = Enums.QueryType.KeyPerformanceIndicators Or queryType = Enums.QueryType.TelecontroAnalysis Then
_recordCount = _myDataset.Tables(0).Rows(0).Item("RecordCount")
Else
'The query is grouped therefore count the number of records in the table
_recordCount = _myDataset.Tables(0).Rows.Count
End If
Else
_recordCount = 0
End If
Catch ex As Exception
Throw
Finally
End Try
End Sub
Ok, problem solved. Removed the try catch block from DoWork and moved my exception handling into 'RunWorkerCompleted' using e.error. Some reading of the documentation (RTFM...), highlighted the fact that using Try/Catch in the worker thread interferes with the native functionality of the BackgroundWorker. Thanks again everyone for your input.
Paul,
I made an application that our company uses to launch databases and updates them on the users machine, when needed.
I am having a slight problem when it comes to launching databases and the database starts up slow. When this occurs my application throws an exception, as I assuming its awaiting some kind of response back.
As of now the error thrown is: The system cannot find the file specified
I am trying to prevent this exception logging for cases like this(Slow Application), but still allow the logging if a real error occurs while opening a database.
Current Code I am using:
Private Sub OpenApplication()
If File.Exists(LocalPathString) Then ' File Found. Open the File.
Try
Dim ps As New Process
ps = Process.Start(LocalPathString)
Catch ex As Exception
ex.Source += " | " & LocalPathString
RaiseEvent ShowError(ex)
Finally
RaiseEvent CancelIt() ' Thread Complete. Close the ActionForm
End Try
Else
If LocalPathString = vbNullString Then
RaiseEvent CancelIt() ' No file exits. Cancel thread.
Else
RaiseEvent ShowError(New Exception("Database Not Located: " & LocalPathString))
End If
End If
End Sub
StackTrace:
System.Diagnostics.Process.StartWithShellExecuteEx(startInfo As ProcessStartInfo)
App.exe: N 00912
System.Diagnostics.Process.Start()
App.exe: N 00136
System.Diagnostics.Process.Start(startInfo As ProcessStartInfo)
App.exe: N 00049
SAMi.ActionClass.OpenApplication()
App.exe: N 00117
Maybe I'm missing something, but why don't you simply omit the logging if you found that specific exception?
Catch ex As Exception
ex.Source += " | " & LocalPathString
if not ex.Message.Contains("The system cannot find the file specified") Then
RaiseEvent ShowError(ex)
end if
I'm trying to safely kill a thread. In my button click I have:
try
dim bar as new foo()
dim mythread as New System.Threading.Thread(AddressOf bar.Start)
mythread.Start()
sleep(1000)
mythread.abort()
catch ex as Exception
msgbox ex.Message
end try
In my Class I have:
class foo
public function Start()
Try
do some stuff...
Catch tae As ThreadAbortException
Thread.ResetAbort()
Catch ex As Exception
LogData("[ ERROR ] ", "[ Start ]" & ex.Message & " line: " & Erl())
End Try
end sub
end class
When it goes to abort the thread I still get a thread abort error. What am I doing wrong?
It's really impossible to "safely" abort a thread. You should, instead, focus on having a mechanism where you can notify the thread that it should exit, and allow it to cooperatively exit (via returning from its main entry point method).