2016-07-25 5 views
0

こんにちは、もう一度StackOverflowコミュニティ!VB.Net BackgroundWorkerとAsyncCancelが正しく動作しない

BackgroundWorkerとAsyncCancelに問題があります。 BackgroundWorkerは電子メールを送信するだけですが、タスクまたは電子メールがいつ送信されたかを報告し、タスクまたは電子メールの送信をキャンセルできるようにしたいと考えています。

問題はキャンセルを押した後も引き続きエラーを報告し、取り消されません。

ご協力いただきありがとうございます。

ありがとうございました!

Private Sub Sendmail_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load 

    StatusLabel.Text &= "Idle" 

End Sub 

Private Sub SendmailBackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles SendmailBackgroundWorker.DoWork 

    Try 

     Dim Smtp As New SmtpClient() 
     Dim Email As New MailMessage() 

     Smtp.Port = 25 
     Smtp.Host = "mail.server.com" 

     Smtp.EnableSsl = False 
     Smtp.UseDefaultCredentials = False 

     Smtp.Credentials = New Net.NetworkCredential("[email protected]", "password") 

     Email = New MailMessage() 
     Email.From = New MailAddress(FromTextBox.Text) 
     Email.To.Add(ToTextBox.Text) 
     Email.Subject = SubjectTextBox.Text 
     Email.IsBodyHtml = False 
     Email.Body = BodyTextBox.Text 

     Smtp.Send(Email) 

    Catch ex As Exception 

     MsgBox("Sendmail Error!" & vbNewLine & vbNewLine & ex.ToString) 

    End Try 

    If SendmailBackgroundWorker.CancellationPending Then 

     StatusLabel.Text = "Canceling" 
     e.Cancel = True 

    End If 

End Sub 

Private Sub SendmailBackgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles SendmailBackgroundWorker.RunWorkerCompleted 

    StatusLabel.Text = "Status: " 

    If (e.Error IsNot Nothing) Then 


     StatusLabel.Text &= "Worker Error!" & vbNewLine & vbNewLine & e.Error.Message 

    ElseIf e.Cancelled Then 

     StatusLabel.Text &= "Canceled!" 

    Else 

     StatusLabel.Text &= "Sent!" 

    End If 

    SendButton.Enabled = True 
    CancelButton.Enabled = False 

End Sub 

Private Sub SendButton_Click(sender As Object, e As EventArgs) Handles SendButton.Click 

    StatusLabel.Text = "Status: " 

    SendButton.Enabled = False 
    CancelButton.Enabled = True 

    SendmailBackgroundWorker.WorkerSupportsCancellation = True 
    SendmailBackgroundWorker.WorkerReportsProgress = True 

    StatusLabel.Text &= "Sending..." 

    SendmailBackgroundWorker.RunWorkerAsync() 

End Sub 

Private Sub CancelButton_Click(sender As Object, e As EventArgs) Handles CancelButton.Click 

    CancelButton.Enabled = False 
    SendmailBackgroundWorker.CancelAsync() 

End Sub 
+0

その他の問題は、メールの送信が非常に迅速になることです。ユーザーが送信をキャンセルする時間さえ持っていない可能性があります。 – Enigmativity

答えて

1

それが必要として正確に動作していること:

は、ここに私の完全なコードマイナスのコメントや輸入があります。問題は、それがどのように動作するかを正しく読まなかったことです。 BackgroundWorkerCancelAsync(​​)を電話しても何もキャンセルされません。それだけでは、BackgroundWorkerオブジェクトにフラグが設定されます。 DoWorkイベントハンドラでそのフラグをテストするのはあなた次第です。設定されていれば、作業を中止することができます。あなたの現在のコードでは、電子メールが送信されてからキャンセルするかどうかにかかわらず電子メールが送信されるまで、そのフラグをテストしていません。

BackgroundWorkerがキャンセルできることを過大評価しています。 BackgroundWorker自体は、DoWorkイベントハンドラであなたが何をしているのかわからないので、単純に中止することはありません。これは、コード内の適切なポイントでタスクを終了する機会を与えます。適切なポイントがない場合は、何もキャンセルできません。

あなたのSmtpClientSendを呼び出すと、その同期メソッドが返されるまで何もできないので、キャンセルすることはできません。あなたがしなければならないのは、BackgroundWorkerを使用するのではなく、SmtpClientクラスに組み込まれた非同期機能です。それはSendAsyncメソッドとSendAsyncCancelメソッドを持っていますので、マルチスレッド化を処理させることができます。

+0

Enigmativityとjmcilhinneyの助けてくれてありがとう、私はこれを朝に調べる予定です。 –

関連する問題