2016-07-20 58 views
0

你好再次StackOverflow社區!VB.Net線程和Addhandler問題

我正在研究「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("[email protected]", "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("[email protected]", "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對象到該郵件發送者和使用利用其InvokeRequiredInvoke/BeginInvoke成員編組方法調用到UI線程。