|
-
Jul 18th, 2013, 07:39 PM
#1
Thread Starter
Frenzied Member
Try Catch Exit Sub
Hi guys I have been googling around and a bit confused. I have a try statement in my code would like if an exception is caught to exit the sub and start over. My code is reading data into a DataTable , when an error is caught and I hit the button to start the sub again the data is still in the table.
Example:
I have a table with 1 address
Hit button to send email, address is retrieved , if there is a problem sending the email it is caught in the catch block
if I hit the button again to send email now I have 2 address's
Bottom line is I am confused as to how to properly code this to handle errors correctly, exit the sub and resume
In my googling efforts I came across some posts about NOT exiting a sub but using return instead
can someone give me some guidance thanks
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
GetEmailAdd() 'function to readtable from txt file
Dim attach As Attachment = Nothing
If CheckBox1.Checked Then
Dim filename As String = OpenFileDialog2.FileName
attach = New Attachment(filename)
End If
Dim i As Integer = 1
Dim pauseTime As Integer = CDbl(txttimesecs.Text) * 1000
Dim result As DialogResult = MessageBox.Show("There are" & " " & emailadd.Count & " " & "Messages to be Sent", "Send Email", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
If result = DialogResult.Cancel Then
Return
End If
For Each email In emailadd
If emailadd.Count <= 0 Then
MsgBox("No Email Address Found")
Exit Sub
End If
Try
i = +1
Dim sslValue As String = ComboBox1.Text
Dim SmtpServer As New SmtpClient()
Dim mail As New MailMessage()
SmtpServer.Credentials = New Net.NetworkCredential(txtusername.Text, txtpassword.Text)
SmtpServer.Port = CDbl(txtserverport.Text)
SmtpServer.Host = txtservername.Text
SmtpServer.EnableSsl = sslValue
mail = New MailMessage()
mail.From = New MailAddress(txtfrom.Text)
mail.To.Add(email)
mail.Subject = txtsubj.Text
If CheckBox1.Checked Then
mail.Attachments.Add(attach)
End If
mail.Body = txtmsgbox.Text
If btnhtml.Checked = True Then
mail.IsBodyHtml = True
Else
mail.IsBodyHtml = False
End If
SmtpServer.Send(mail)
Catch ex As Exception
MsgBox(ex.ToString)
MsgBox("No Messages Sent")
Exit Try
Return
End Try
Next
wait(pauseTime)
MsgBox(i.ToString & " " & "Messages Sent")
End Sub
-
Jul 18th, 2013, 08:40 PM
#2
-
Jul 18th, 2013, 09:39 PM
#3
Re: Try Catch Exit Sub
You don't need the Exit Try in there, it won't do any good. Also, the "Wait" statement makes me nervous.
However, aren't you getting your email addresses in the function GetEmailAdd? That could easily duplicate the addresses, depending on how it is written. It looks like it probably populates a form level collection. If it doesn't clear that collection as a first step, it will just keep adding new ones on every button click.
My usual boring signature: Nothing
 
-
Jul 18th, 2013, 11:07 PM
#4
Thread Starter
Frenzied Member
Re: Try Catch Exit Sub
Thanks Shaggy I added:
emailadd.Clear()
at the top to clear the collection, that seems to do the trick
Can I ask why the "wait" has you nervous?
-
Jul 19th, 2013, 11:06 AM
#5
Re: Try Catch Exit Sub
Can I ask why the "wait" has you nervous?
He suspects that you have a loop whirring around doing nothing but checking some value a million times a second eating up CPU, memory and generally doing bad things. If you have, best to say nothing but quietly remove it and replace it with a less damaging method. We don't need another rant! [Ducks out whispering, "I was never here"]
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Jul 19th, 2013, 11:14 AM
#6
Re: Try Catch Exit Sub
Yeah, I've become a bit predictable about that. The method doesn't look like a standard method, it looks like something custom, and with a name like that, it sure sounds like a busy wait, which is kind of my favorite rant.
My usual boring signature: Nothing
 
-
Jul 19th, 2013, 11:40 AM
#7
Thread Starter
Frenzied Member
Re: Try Catch Exit Sub
Here is what I am doing. Is there a better method? Thanks for your help
Code:
Public Sub pause(ByVal seconds As Single)
Dim newDate As Date
newDate = DateAndTime.Now.AddSeconds(seconds)
While DateAndTime.Now.Second < newDate.Second
Threading.Thread.Sleep(100)
End While
End Sub
Public Sub wait(ByVal interval As Integer)
Dim stopW As New Stopwatch
stopW.Start()
Do While stopW.ElapsedMilliseconds < interval
' Allows your UI to remain responsive
Application.DoEvents()
Loop
stopW.Stop()
End Sub
-
Jul 19th, 2013, 12:34 PM
#8
Re: Try Catch Exit Sub
Well, there isn't a worse way. That is exactly what I thought the method would be: A busy wait. It's the one thing I know of that can harm every other program running on you computer, and could theoretically even harm the computer itself. Basically, don't do it, and if you can't think of a better way...still don't do it.
Waiting in place is mostly a mental mistake. People expect a program to be a linnear sequence of events, so as they think it through they think, "and then I want to pause for a bit." Pausing with Thread.Sleep is fine, except that it freezes the UI (if that is thre thread that is sleeping, as it is in your code). The cost of sleeping is nothing at all, since the thread gives up its time on the CPU for the duration of the sleep. Doing that in a loop isn't particularly harmful, either, as it wakes up enough to perform the trivial loop, then goes right back to sleep. So, your pause method will freeze the UI, but does nothing else bad. If that is acceptable, it's also harmless, but kind of odd, since it does nothing and freezes the UI.
The Wait method is a different matter. The CPU will be utterly pegged during the time that is running, even though nothing is being accomplished. This increases power draw, increases heat, and blocks every other process on the system from running efficiently, since once core of the CPU will be locked up completely. That's the rant that I seem to be known for.
JMC has posted a non-busy wait means of a wait method over in the .NET CodeBank, so if you really must wait in line, that would be the way to do it. It's quite a bit more complex than the simple spin around DoEvents of a busy wait, but it doesn't cause the harm of a busy wait, either. However, the traditional way to perform a wait is with a timer, though that requires a different way to think about the problem. In your code, I'm not sure what the wait accomplishes, since it just seems to be a pause for a certain amount of time followed by a messagebox being shown. You could just as easily have a timer on the form, then in place of the wait you would set the interval of the timer and start it. Then, in the tick event for the timer, you'd stop the timer and show the messagebox. That would accomplish the same thing that you have, though it wouldn't be much.
My usual boring signature: Nothing
 
-
Jul 21st, 2013, 06:53 AM
#9
Re: Try Catch Exit Sub
The whole wait/pause sub is pointless. The line wont execute until the email has been sent. So why wait? I don't need to re write on what's already been said. It's shocking abuse. Maybe i am over reacting :/ Regardless if you want the UI to remain responsive the use the Async method. MSDN should always be your first stop. SmtpClient.SendAsync Method (MailMessage, Object)
Sends the specified e-mail message to an SMTP server for delivery. This method does not block the calling thread and allows the caller to pass an object to the method that is invoked when the operation completes.
-
Jul 21st, 2013, 08:48 AM
#10
Re: Try Catch Exit Sub
I've had issues with message sending and used SendCompletedCallback as per Ident. The following can not be executed as is, the idea is to show a tad bit more (like getting InnerException) for the call back then in the example with the MSDN docs.
Code:
Public Class frmMainForm
Sub SendMail()
Using Mail As New MailMessage()
Mail.From = New MailAddress(txtFromAddress.Text, txtFromDisplayName.Text)
Mail.To.Add(New MailAddress(txtSendAddress.Text, txtSendToDisplayName.Text))
Mail.Subject = txtSubject.Text
Dim plainView As AlternateView = AlternateView.CreateAlternateViewFromString(My.Resources.PlainTextFormatted, Nothing, "text/plain")
Dim htmlView As AlternateView = AlternateView.CreateAlternateViewFromString(My.Resources.HtmlFormatted, Nothing, "text/html")
Mail.AlternateViews.Add(plainView)
Mail.AlternateViews.Add(htmlView)
Mail.IsBodyHtml = chkUseHtmlBody.Checked
Dim MailClient As New SmtpClient("******************")
MailClient.EnableSsl = chkEnableSsl.Checked
If PortNumericUpDown.Value > 0 Then
MailClient.Port = CInt(PortNumericUpDown.Value)
End If
txtResults.AppendText(String.Format("Connection Name: '{0}'", MailClient.ServicePoint.ConnectionName) & Environment.NewLine)
MailClient.UseDefaultCredentials = True
AddHandler MailClient.SendCompleted, AddressOf SendCompletedCallback
Dim UserToken As String = "******"
MailClient.Timeout = CInt(TimeOutNumericUpDown.Value)
MailClient.SendAsync(Mail, UserToken)
End Using
End Sub
Private password As String = ""
Private mailSent As Boolean = False
Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
Dim token As String = CStr(e.UserState)
txtResults.AppendText(String.Format("Call back at {0} token [{1}]", Now, token) & Environment.NewLine)
If e.Cancelled Then
txtResults.AppendText(String.Format("[{0}] [{1}] Send canceled.", Now, token) & Environment.NewLine)
End If
If e.Error IsNot Nothing Then
txtResults.AppendText(String.Format("[{0}] [{1} [{2}]] Send canceled.", Now, token, e.Error.ToString) & Environment.NewLine)
GetInnerException(e.Error)
My.Dialogs.ExceptionDialog(e.Error, "Failed see results.", "")
ActiveControl = txtResults
Else
txtResults.AppendText("Message sent at '" & Now.ToString & "'" & Environment.NewLine)
MessageBox.Show("Message sent!!!")
End If
mailSent = True
End Sub
Private Function GetInnerException(ByRef sender As Exception) As String
Dim Data As String = String.Empty
txtResults.AppendText(Environment.NewLine)
Do While Not sender Is Nothing
Data &= sender.ToString()
txtResults.AppendText(String.Format("[{0}]", sender.Message) & Environment.NewLine)
sender = sender.InnerException
Loop
Return Data
End Function
Private Sub cmdSendMessage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSendMessage.Click
txtResults.AppendText("Sending mail begin at '" & Now.ToString & "'" & Environment.NewLine)
SendMail()
txtResults.AppendText("Done executing commands at '" & Now.ToString & "'" & Environment.NewLine)
End Sub
End Class
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|