Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Se você tiver uma operação que levará muito tempo para ser concluída e não quiser causar atrasos na interface do usuário, poderá usar a classe BackgroundWorker para executar a operação em outro thread.
Para obter uma lista completa do código usado neste exemplo, consulte Como executar uma operação em segundo plano.
Executar uma operação em segundo plano
Com o formulário ativo no Windows Forms Designer no Visual Studio, arraste dois controles
do Caixa de Ferramentas para o formulário e defina as propriedades e dos botões de acordo com a tabela a seguir. Botão Nome Texto button1startBtnInício button2cancelBtnCancelar Abra aCaixa de Ferramentas do
, clique na guia Componentes do e arraste o componente para o formulário. O componente
backgroundWorker1aparece na bandeja de componentes .Na janela Propriedades , defina a propriedade WorkerSupportsCancellation como
true.Na janela Propriedades, clique no botão Eventos e, em seguida, clique duas vezes nos eventos DoWork e RunWorkerCompleted para criar manipuladores de eventos.
Insira o seu código demorado no manipulador de eventos DoWork.
Extraia todos os parâmetros exigidos pela operação da propriedade Argument do parâmetro DoWorkEventArgs.
Atribua o resultado do cálculo à propriedade Result do DoWorkEventArgs.
Isso estará disponível para o manipulador de eventos RunWorkerCompleted.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // Do not access the form's BackgroundWorker reference directly. // Instead, use the reference provided by the sender parameter. BackgroundWorker bw = sender as BackgroundWorker; // Extract the argument. int arg = (int)e.Argument; // Start the time-consuming operation. e.Result = TimeConsumingOperation(bw, arg); // If the operation was canceled by the user, // set the DoWorkEventArgs.Cancel property to true. if (bw.CancellationPending) { e.Cancel = true; } }Private Sub backgroundWorker1_DoWork( _ sender As Object, e As DoWorkEventArgs) _ Handles backgroundWorker1.DoWork ' Do not access the form's BackgroundWorker reference directly. ' Instead, use the reference provided by the sender parameter. Dim bw As BackgroundWorker = CType( sender, BackgroundWorker ) ' Extract the argument. Dim arg As Integer = Fix(e.Argument) ' Start the time-consuming operation. e.Result = TimeConsumingOperation(bw, arg) ' If the operation was canceled by the user, ' set the DoWorkEventArgs.Cancel property to true. If bw.CancellationPending Then e.Cancel = True End If End SubInsira o código para recuperar o resultado da sua operação no manipulador de eventos RunWorkerCompleted.
// This event handler demonstrates how to interpret // the outcome of the asynchronous operation implemented // in the DoWork event handler. private void backgroundWorker1_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { // The user canceled the operation. MessageBox.Show("Operation was canceled"); } else if (e.Error != null) { // There was an error during the operation. string msg = String.Format("An error occurred: {0}", e.Error.Message); MessageBox.Show(msg); } else { // The operation completed normally. string msg = String.Format("Result = {0}", e.Result); MessageBox.Show(msg); } }' This event handler demonstrates how to interpret ' the outcome of the asynchronous operation implemented ' in the DoWork event handler. Private Sub backgroundWorker1_RunWorkerCompleted( _ sender As Object, e As RunWorkerCompletedEventArgs) _ Handles backgroundWorker1.RunWorkerCompleted If e.Cancelled Then ' The user canceled the operation. MessageBox.Show("Operation was canceled") ElseIf (e.Error IsNot Nothing) Then ' There was an error during the operation. Dim msg As String = String.Format("An error occurred: {0}", e.Error.Message) MessageBox.Show(msg) Else ' The operation completed normally. Dim msg As String = String.Format("Result = {0}", e.Result) MessageBox.Show(msg) End If End SubImplemente o método
TimeConsumingOperation.// This method models an operation that may take a long time // to run. It can be cancelled, it can raise an exception, // or it can exit normally and return a result. These outcomes // are chosen randomly. private int TimeConsumingOperation( BackgroundWorker bw, int sleepPeriod ) { int result = 0; Random rand = new Random(); while (!bw.CancellationPending) { bool exit = false; switch (rand.Next(3)) { // Raise an exception. case 0: { throw new Exception("An error condition occurred."); break; } // Sleep for the number of milliseconds // specified by the sleepPeriod parameter. case 1: { Thread.Sleep(sleepPeriod); break; } // Exit and return normally. case 2: { result = 23; exit = true; break; } default: { break; } } if( exit ) { break; } } return result; }' This method models an operation that may take a long time ' to run. It can be cancelled, it can raise an exception, ' or it can exit normally and return a result. These outcomes ' are chosen randomly. Private Function TimeConsumingOperation( _ bw As BackgroundWorker, _ sleepPeriod As Integer) As Integer Dim result As Integer = 0 Dim rand As New Random() While Not bw.CancellationPending Dim [exit] As Boolean = False Select Case rand.Next(3) ' Raise an exception. Case 0 Throw New Exception("An error condition occurred.") Exit While ' Sleep for the number of milliseconds ' specified by the sleepPeriod parameter. Case 1 Thread.Sleep(sleepPeriod) Exit While ' Exit and return normally. Case 2 result = 23 [exit] = True Exit While Case Else Exit While End Select If [exit] Then Exit While End If End While Return result End FunctionNo Windows Forms Designer, clique duas vezes em
startButtonpara criar o manipulador de eventos Click.Chame o método RunWorkerAsync no manipulador de eventos Click para
startButton.private void startBtn_Click(object sender, EventArgs e) { this.backgroundWorker1.RunWorkerAsync(2000); }Private Sub startButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles startBtn.Click Me.backgroundWorker1.RunWorkerAsync(2000) End SubNo Windows Forms Designer, clique duas vezes em
cancelButtonpara criar o manipulador de eventos Click.Chame o método CancelAsync no manipulador de eventos Click para
cancelButton.private void cancelBtn_Click(object sender, EventArgs e) { this.backgroundWorker1.CancelAsync(); }Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cancelBtn.Click Me.backgroundWorker1.CancelAsync() End SubNa parte superior do arquivo, importe os namespaces System.ComponentModel e System.Threading.
using System; using System.ComponentModel; using System.Drawing; using System.Threading; using System.Windows.Forms;Imports System.ComponentModel Imports System.Drawing Imports System.Threading Imports System.Windows.FormsPressione F6 para criar a solução e, em seguida, pressione Ctrl+F5 para executar o aplicativo fora do depurador.
Observação
Se você pressionar F5 para executar o aplicativo sob o depurador, a exceção gerada no método
TimeConsumingOperationé capturada e exibida pelo depurador. Quando você executa o aplicativo fora do depurador, o BackgroundWorker manipula a exceção e a armazena em cache na propriedade Error do RunWorkerCompletedEventArgs.Clique no botão Iniciar para executar uma operação assíncrona e, em seguida, clique no botão Cancelar para interromper uma operação assíncrona em execução.
O resultado de cada operação é apresentado num MessageBox.
Próximos passos
Implemente um formulário que relate o progresso à medida que uma operação assíncrona prossegue. Para obter mais informações, consulte Como implementar um formulário que usa uma operação em segundo plano.
Implemente uma classe que ofereça suporte ao padrão assíncrono para componentes. Para obter mais informações, consulte Implementando o padrão assíncrono baseado em evento.
Ver também
.NET Desktop feedback