再次问好StackOverflow社区!
我正在研究一个“SendLogfileClass”类。在这个课程中,我通过电子邮件将日志文件发送到所述电子邮件帐户那部分按预期工作。我遇到的问题是尝试处理异步完成事件。在上述事件期间,Addhandler将触发并在主窗体上设置StatusBar.StatusLabel。
以下是一些相关的代码块:
#Region "Imports"
Imports System
Imports System.Net
Imports System.Net.Mail
Imports System.Net.Mime
Imports System.Threading
Imports System.ComponentModel
Imports System.IO
#End Region
Public Class Form1
#Region "Public"
Private SendmailThread As Thread
Private MailBody As String = Nothing
#End Region
#Region "Private"
Private mailSent As Boolean = False
#End Region
Public Function GetTimestamp() As String
Dim t As Date = Date.Now
Dim timestamp As String = Nothing
Try
timestamp = t.ToLongTimeString & " " & t.ToLongDateString
Catch ex As Exception
Return 1
End Try
Return timestamp
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
If LoggerClock.Enabled = True Then
OutputConsole.Text = "logger Started: " & GetTimestamp() & vbNewLine
OutputConsole.AppendText("Logfile Opened: " & GetTimestamp() & vbNewLine)
StatusLabel.Text = "Logger Status: Active"
StatusBar.Refresh()
Else
OutputConsole.Text = "logger Started: " & GetTimestamp() & vbNewLine
StatusLabel.Text = "Logger Status: Inactive"
StatusBar.Refresh()
End If
SendlogClock.Enabled = True
ToggleViewForm(1)
Catch ex As Exception
Exit Sub
End Try
End Sub
Public Function SetStatus(ByVal [status] As String) As Integer
Try
Thread.Sleep(1000)
StatusLabel.Text = [status]
StatusBar.Refresh()
Catch ex As Exception
Return 1
End Try
Return 0
End Function
Private Sub SendlogThreadTask()
Try
SendLogfile("user@gmail.com", "Logger Logfile", MailBody).ToString()
Catch ex As Exception
Exit Sub
End Try
End Sub
Private Sub SendlogClock_Tick(sender As Object, e As EventArgs) Handles SendlogClock.Tick
Try
OutputConsole.AppendText("Logfile Closed: " & GetTimestamp() & vbNewLine)
SendmailThread = New Thread(AddressOf SendlogThreadTask)
SendmailThread.IsBackground = True
SendmailThread.Start()
OutputConsole.ResetText()
OutputConsole.Text = "Logfile Opened: " & GetTimestamp() & vbNewLine
Catch ex As Exception
Exit Sub
End Try
End Sub
Public Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
Try
' Get the unique identifier for this asynchronous operation.
Dim token As String = CStr(e.UserState)
If e.Cancelled Then
StatusLabel.Text = "Send Canceled... " & token
StatusBar.Refresh()
End If
If e.Error IsNot Nothing Then
StatusLabel.Text = "Error: " & token & " " & e.Error.ToString() & " "
StatusBar.Refresh()
Else
StatusLabel.Text = "Message Sent... "
StatusBar.Refresh()
End If
mailSent = True
Catch ex As Exception
Exit Sub
End Try
End Sub
Public Function SendLogfile(ByVal mailTo As String, ByVal mailSubject As String, ByVal mailBody As String, Optional ByVal doAttach As Boolean = False, Optional ByVal messageAttach As String = Nothing) As Integer
Try
' SMTP Server
Dim SmtpServer As String = "mail.domain.com"
' Command line argument must the the SMTP host.
Dim Cli As New SmtpClient(SmtpServer)
' Specify the e-mail sender.
' Create a mailing address that includes a UTF8 character
' in the display name.
Dim [from] As New MailAddress("logger@domain.com", "logger " & ChrW(&HD8) & " logs", System.Text.Encoding.UTF8)
' Set destinations for the e-mail message.
Dim [to] As New MailAddress(mailTo)
' Specify the message content.
Dim message As New MailMessage([from], [to])
message.Body = mailBody
' Include some non-ASCII characters in body and subject.
Dim someArrows As New String(New Char() {ChrW(&H2190), ChrW(&H2191), ChrW(&H2192), ChrW(&H2193)})
message.Body += Environment.NewLine & someArrows
message.BodyEncoding = System.Text.Encoding.UTF8
message.Subject = mailSubject & someArrows
message.SubjectEncoding = System.Text.Encoding.UTF8
' Put the mail attachment in a list of items
'Dim attachment As New Attachment(messageAttach)
' Attach file.
'If doAttach = True Then
'If File.Exists(messageAttach) Then
'message.Attachments.Add(attachment)
'End If
'End If
' Set the method that is called back when the send operation ends.
AddHandler Cli.SendCompleted, AddressOf SendCompletedCallback
' The userState can be any object that allows your callback
' method to identify this send operation.
' For this example, the userToken is a string constant.
Dim userState As String = "OK"
Cli.SendAsync(message, userState)
'MsgBox("Sending message... press c to cancel mail. Press any other key to exit.")
Dim answer As String = "OK" ' or CANCEL
' If the user canceled the send, and mail hasn't been sent yet,
' then cancel the pending operation.
If answer.StartsWith("C") AndAlso mailSent = False Then
Cli.SendAsyncCancel()
End If
' Clean up.
message.Dispose()
Catch ex As Exception
MsgBox("Encountered Error: " & vbNewLine & vbNewLine & ex.ToString())
Return 1
End Try
Return 0
End Function
End Class
答案 0 :(得分:0)
您的事件处理程序在辅助线程上执行,在该事件处理程序中,您指的是MainForm
的默认实例。默认实例是特定于线程的,因此它是与您在屏幕上查看的对象不同的表单对象。
您通常可以使用SynchronizationContext
类来启用对UI线程的方法调用的编组,但在您的情况下这是不可能的,因为您实际上也是在辅助线程上创建对象。在这种情况下,您必须将对现有MainForm
对象的引用传递给该邮件发件人,并使用它来使用其InvokeRequired
和Invoke
封送对UI线程的方法调用。 / BeginInvoke
成员。