Partilhar via


Demonstra Passo a passo: Criação de um componente Multithreaded simples com Visual Basic

O BackgroundWorker componente substitui e adiciona funcionalidade para o System.Threading namespace; No entanto, o System.Threading namespace é mantido para compatibilidade com versões anteriores e o uso futuro, se você escolher. Para obter mais informações, consulte Visão geral sobre o componente BackgroundWorker.

Você pode escrever aplicativos que são capazes de realizar várias tarefas simultaneamente. Essa capacidade, chamada multithreading, ou livre de threading, é uma maneira eficiente para design de componentes que fazem uso intenso do processador e exigem entrada do usuário. Um exemplo de um componente que pode fazer uso de multithreading seria um componente que calcula informações de folha de pagamento. O componente pode processar dados inseridos em um banco de dados por um usuário em um segmento enquanto os cálculos de folha de pagamento de uso intenso do processador foram realizados em outro. Executando esses processos em threads separados, os usuários não precisam esperar o computador concluir cálculos antes de inserir dados adicionais. Esta explicação passo a passo, você irá criar um componente multithreaded simples que executa vários cálculos complexos simultaneamente.

Criando o projeto

Seu aplicativo consistirá em um único formulário e um componente. O usuário digitará os valores e o sinal para o componente para iniciar os cálculos. O formulário, em seguida, irá receber os valores de seu componente e exibi-los em controles de rótulo. O componente irá executar os cálculos de uso intenso do processador e o formulário após a conclusão de sinal. Você irá criar variáveis públicas em seu componente para armazenar valores recebidos de interface do usuário. Você também irá implementar métodos em seu componente para executar os cálculos com base nos valores dessas variáveis.

ObservaçãoObservação

Enquanto uma função geralmente é preferível para um método que calcula um valor, argumentos não podem ser passados entre threads, nem os valores podem ser retornados. Há várias maneiras simples de fornecer valores para threads e receber os valores deles. Nesta demonstração, retornará valores para a interface do usuário, atualizando variáveis públicas e eventos serão usados para notificar o programa principal quando um thread concluiu a execução.

As caixas de diálogo e comandos de menu demonstradas podem ser diferentes daqueles descritos na Ajuda, dependendo das configurações ativas ou configurações de edição. Para alterar as configurações, escolha Import and Export Settings sobre o Ferramentas menu. Para obter mais informações, consulte Trabalhando com configurações.

Para criar o formulário

  1. Criar um novo projeto Windows Application.

  2. Nomeie o aplicativo Calculations e renomeie Form1.vb como frmCalculations.vb.

  3. Quando o Visual Studio solicita que você renomeie o Form1 o elemento de código, clique em Sim.

    Este formulário servirá como a interface de usuário principal para o seu aplicativo.

  4. Adicionar cinco Label controles, quatro Button controles e um TextBox o controle ao seu formulário.

    Controle

    Nome

    Texto

    Label1

    lblFactorial1

    (vazio)

    Label2

    lblFactorial2

    (vazio)

    Label3

    lblAddTwo

    (vazio)

    Label4

    lblRunLoops

    (vazio)

    Label5

    lblTotalCalculations

    (vazio)

    Button1

    btnFactorial1

    Fatorial

    Button2

    btnFactorial2

    Fatorial - 1

    Button3

    btnAddTwo

    Adicionar dois

    Button4

    btnRunLoops

    Executar um Loop.

    TextBox1

    txtValue

    (vazio)

Para criar o componente de Calculadora

  1. Do projeto menu, selecione Adicionar o componente.

  2. Este componente de nome Calculator.

Para adicionar variáveis públicas para o componente de Calculadora

  1. Abrir o O Editor de código para Calculator.

  2. Adicione instruções para criar variáveis públicas que você usará para passar valores de frmCalculations para cada segmento.

    A variável varTotalCalculations manter um total contínuo do número total de cálculos realizado pelo componente e outras variáveis serão receberão valores do formulário.

    Public varAddTwo As Integer
    Public varFact1 As Integer
    Public varFact2 As Integer
    Public varLoopValue As Integer
    Public varTotalCalculations As Double = 0
    

Para adicionar métodos e eventos para o componente de Calculadora

  1. Declare os eventos que seu componente usará para se comunicar valores ao seu formulário. Imediatamente abaixo de declarações de variáveis inseridas na etapa anterior, digite o seguinte código:

    Public Event FactorialComplete(ByVal Factorial As Double, ByVal _
       TotalCalculations As Double)
    Public Event FactorialMinusComplete(ByVal Factorial As Double, ByVal _
       TotalCalculations As Double)
    Public Event AddTwoComplete(ByVal Result As Integer, ByVal _
       TotalCalculations As Double)
    Public Event LoopComplete(ByVal TotalCalculations As Double, ByVal _
       Counter As Integer)
    
  2. Imediatamente abaixo de declarações de variáveis inseridas na etapa 1, digite o seguinte código:

    ' This sub will calculate the value of a number minus 1 factorial 
    ' (varFact2-1!).
    Public Sub FactorialMinusOne()
       Dim varX As Integer = 1
       Dim varTotalAsOfNow As Double
       Dim varResult As Double = 1
       ' Performs a factorial calculation on varFact2 - 1.
       For varX = 1 to varFact2 - 1
          varResult *= varX
          ' Increments varTotalCalculations and keeps track of the current
          ' total as of this instant.
          varTotalCalculations += 1
          varTotalAsOfNow = varTotalCalculations
       Next varX
       ' Signals that the method has completed, and communicates the 
       ' result and a value of total calculations performed up to this 
       ' point
       RaiseEvent FactorialMinusComplete(varResult, varTotalAsOfNow)
    End Sub
    
    ' This sub will calculate the value of a number factorial (varFact1!).
    Public Sub Factorial()
       Dim varX As Integer = 1
       Dim varResult As Double = 1
       Dim varTotalAsOfNow As Double = 0
       For varX = 1 to varFact1
           varResult *= varX
           varTotalCalculations += 1
           varTotalAsOfNow = varTotalCalculations
       Next varX
       RaiseEvent FactorialComplete(varResult, varTotalAsOfNow)
    End Sub
    
    ' This sub will add two to a number (varAddTwo + 2).
    Public Sub AddTwo()
       Dim varResult As Integer
       Dim varTotalAsOfNow As Double
       varResult = varAddTwo + 2
       varTotalCalculations += 1
       varTotalAsOfNow = varTotalCalculations
       RaiseEvent AddTwoComplete(varResult, varTotalAsOfNow)
    End Sub
    
    ' This method will run a loop with a nested loop varLoopValue times.
    Public Sub RunALoop()
       Dim varX As Integer
       Dim varY As Integer
       Dim varTotalAsOfNow As Double
       For varX = 1 To varLoopValue
          ' This nested loop is added solely for the purpose of slowing
          ' down the program and creating a processor-intensive
          ' application.
          For varY = 1 To 500
             varTotalCalculations += 1
             varTotalAsOfNow = varTotalCalculations
          Next
       Next
       RaiseEvent LoopComplete(varTotalAsOfNow, varX - 1)
    End Sub
    

A transferência de entrada do usuário para o componente.

A próxima etapa é adicionar código para frmCalculations para receber entrada do usuário e para transferir e receber os valores de e para o Calculator componente.

Para implementar a funcionalidade de front-end para frmCalculations

  1. Selecione Build Solution partir do Build menu.

  2. Abra frmCalculations no Windows Forms Designer.

  3. Localize o Componentes de cálculos guia de Toolbox. Arraste um Calculadora componente na superfície de design.

  4. No Propriedades windows, clique no eventos botão.

  5. Clique duas vezes em cada um dos quatro eventos para criar manipuladores de eventos em frmCalculations. Você precisará retornar ao designer após cada manipulador de eventos é criado.

  6. Insira o seguinte código para manipular os eventos em seu formulário receberá do Calculator1:

    Private Sub Calculator1_AddTwoComplete(ByVal Result As System.Int32, ByVal TotalCalculations As System.Double) Handles Calculator1.AddTwoComplete
        lblAddTwo.Text = Result.ToString
        btnAddTwo.Enabled = True
        lblTotalCalculations.Text = "TotalCalculations are " & _
            TotalCalculations.ToString
    End Sub
    
    Private Sub Calculator1_FactorialComplete(ByVal Factorial As System.Double, ByVal TotalCalculations As System.Double) Handles Calculator1.FactorialComplete
        ' Displays the returned value in the appropriate label.
        lblFactorial1.Text = Factorial.ToString
        ' Re-enables the button so it can be used again.
        btnFactorial1.Enabled = True
        ' Updates the label that displays the total calculations performed
        lblTotalCalculations.Text = "TotalCalculations are " & _
           TotalCalculations.ToString
    End Sub
    
    Private Sub Calculator1_FactorialMinusComplete(ByVal Factorial As System.Double, ByVal TotalCalculations As System.Double) Handles Calculator1.FactorialMinusComplete
        lblFactorial2.Text = Factorial.ToString
        btnFactorial2.Enabled = True
        lblTotalCalculations.Text = "TotalCalculations are " & _
            TotalCalculations.ToString
    End Sub
    
    Private Sub Calculator1_LoopComplete(ByVal TotalCalculations As System.Double, ByVal Counter As System.Int32) Handles Calculator1.LoopComplete
        btnRunLoops.Enabled = True
        lblRunLoops.Text = Counter.ToString
        lblTotalCalculations.Text = "TotalCalculations are " & _
           TotalCalculations.ToString
    End Sub
    
  7. Localize o End Class instrução na parte inferior a O Editor de código. Imediatamente acima dela, adicione o seguinte código para tratar cliques de botão:

    Private Sub btnFactorial1_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnFactorial1.Click
       ' Passes the value typed in the txtValue to Calculator.varFact1.
       Calculator1.varFact1 = CInt(txtValue.Text)
       ' Disables the btnFactorial1 until this calculation is complete.
       btnFactorial1.Enabled = False
       Calculator1.Factorial()
    End Sub
    
    Private Sub btnFactorial2_Click(ByVal sender As Object, ByVal e _
       As System.EventArgs) Handles btnFactorial2.Click
       Calculator1.varFact2 = CInt(txtValue.Text)
       btnFactorial2.Enabled = False
       Calculator1.FactorialMinusOne()
    End Sub
    
    Private Sub btnAddTwo_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnAddTwo.Click
       Calculator1.varAddTwo = CInt(txtValue.Text)
       btnAddTwo.Enabled = False
       Calculator1.AddTwo()
    End Sub
    
    Private Sub btnRunLoops_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnRunLoops.Click
       Calculator1.varLoopValue = CInt(txtValue.Text)
       btnRunLoops.Enabled = False
       ' Lets the user know that a loop is running.
       lblRunLoops.Text = "Looping"
       Calculator1.RunALoop()
    End Sub
    

Teste seu aplicativo.

Agora você criou um projeto que incorpora um formulário e um componente capaz de realizar vários cálculos complexos. Embora você não implementou o recurso de multithreading ainda, você testará o projeto para verificar sua funcionalidade antes de prosseguir.

Para testar seu projeto.

  1. Do Debug menu, escolha Start Debugging. O aplicativo começa e frmCalculations aparece.

  2. Na caixa de texto, digite 4, em seguida, clique no botão Adicionar dois.

    O número "6" deve ser exibido no rótulo abaixo dela e "Total cálculos são de 1" devem ser exibidos em lblTotalCalculations.

  3. Agora, clique no botão fatorial - 1.

    O número "6" deve ser exibido abaixo do botão, e lblTotalCalculations agora lê "Os cálculos são 4".

  4. Alterar o valor na caixa de texto para 20, em seguida, clique no botão fatorial.

    O número "2.43290200817664E + 18" é exibido abaixo dela, e lblTotalCalculations agora lê "Os cálculos são 24".

  5. Alterar o valor na caixa de texto para 50000e em seguida, clique no botão Executar o Loop de um.

    Observe que há um intervalo pequeno, mas perceptível antes que este botão é reativado. O rótulo do botão deve ler "50000" e os cálculos total exibidos são "25000024".

  6. Alterar o valor na caixa de texto para 5000000 e clique no botão rotulado como Executar o Loop de ume clique no botão imediatamente Adicionar dois. Clique em Adicionar dois novamente.

    O botão não responde nem qualquer controle no formulário responderá até que os loops foram concluídos.

    Se o seu programa é executado em um único thread de execução, cálculos de uso intenso do processador como, por exemplo, o exemplo acima têm a tendência a ocupar o programa, até que os cálculos foram concluídos. Na próxima seção, você adicionará multithreading capacidade para seu aplicativo para que vários threads sejam executados ao mesmo tempo.

Adição da funcionalidade de Multithreading

O exemplo anterior demonstrou as limitações de aplicativos executados somente um único segmento de execução. A próxima seção, você usará o Thread classe para adicionar vários threads de execução para o seu componente.

Para adicionar a sub-rotina de Threads

  1. Abrir Calculator.vb no O Editor de código. Próximo à parte superior do código, localize o Public Class Calculator linha. Imediatamente abaixo dela, digite o seguinte:

    ' Declares the variables you will use to hold your thread objects.
    Public FactorialThread As System.Threading.Thread
    Public FactorialMinusOneThread As System.Threading.Thread
    Public AddTwoThread As System.Threading.Thread
    Public LoopThread As System.Threading.Thread
    
  2. Imediatamente antes do End Class a instrução na parte inferior do código, adicione o seguinte método:

    Public Sub ChooseThreads(ByVal threadNumber As Integer)
    ' Determines which thread to start based on the value it receives.
       Select Case threadNumber
          Case 1
             ' Sets the thread using the AddressOf the subroutine where
             ' the thread will start.
             FactorialThread = New System.Threading.Thread(AddressOf _
                Factorial)
             ' Starts the thread.
             FactorialThread.Start()
          Case 2
             FactorialMinusOneThread = New _
                System.Threading.Thread(AddressOf FactorialMinusOne)
             FactorialMinusOneThread.Start()
          Case 3
             AddTwoThread = New System.Threading.Thread(AddressOf AddTwo)
             AddTwoThread.Start()
          Case 4
             LoopThread = New System.Threading.Thread(AddressOf RunALoop)
             LoopThread.Start()
       End Select
    End Sub
    

    Quando um Thread objeto é instanciado, ele requer um argumento na forma de um ThreadStart objeto. O ThreadStart o objeto é um delegado que aponta para o endereço da sub-rotina onde o thread está começar. A ThreadStart objeto não é possível obter parâmetros ou valores de passagem e portanto não pode indicar uma função. O Operador AddressOf (Visual Basic) retorna um delegado que serve como o ThreadStart objeto. O ChooseThreads sub que acabou de ser implementado irá receber um valor a partir do programa chamá-lo e usar esse valor para determinar o segmento apropriado para iniciar.

Para adicionar o código de iniciar o segmento frmCalculations

  1. Abrir o frmCalculations.vb de arquivo no O Editor de código. Localize Sub btnFactorial1_Click.

    1. Comente a linha que chama o Calculator1.Factorialo método diretamente, como mostrado:

      ' Calculator1.Factorial
      
    2. Adicione a seguinte linha para chamar o Calculator1.ChooseThreads método:

      ' Passes the value 1 to Calculator1, thus directing it to start the ' correct thread.
      Calculator1.ChooseThreads(1)
      
  2. Fazer modificações semelhantes a outros button_click sub-rotinas.

    ObservaçãoObservação

    Certifique-se de incluir o valor apropriado para o threads argumento.

    Quando terminar, seu código deve parecer semelhante ao seguinte:

    Private Sub btnFactorial1_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnFactorial1.Click
       ' Passes the value typed in the txtValue to Calculator.varFact1.
       Calculator1.varFact1 = CInt(txtValue.Text)
       ' Disables the btnFactorial1 until this calculation is complete.
       btnFactorial1.Enabled = False
       ' Calculator1.Factorial()
       ' Passes the value 1 to Calculator1, thus directing it to start the
       ' Correct thread.
       Calculator1.ChooseThreads(1)
    End Sub
    
    Private Sub btnFactorial2_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnFactorial2.Click
       Calculator1.varFact2 = CInt(txtValue.Text)
       btnFactorial2.Enabled = False
       ' Calculator1.FactorialMinusOne()
       Calculator1.ChooseThreads(2)
    End Sub
    
    Private Sub btnAddTwo_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnAddTwo.Click
       Calculator1.varAddTwo = CInt(txtValue.Text)
       btnAddTwo.Enabled = False
       ' Calculator1.AddTwo()
       Calculator1.ChooseThreads(3)
    End Sub
    
    Private Sub btnRunLoops_Click(ByVal sender As Object, ByVal e As _
       System.EventArgs) Handles btnRunLoops.Click
       Calculator1.varLoopValue = CInt(txtValue.Text)
       btnRunLoops.Enabled = False
       ' Lets the user know that a loop is running.
       lblRunLoops.Text = "Looping"
       ' Calculator1.RunALoop()
       Calculator1.ChooseThreads(4)
    End Sub
    

Empacotamento de chamadas para controles

Agora você irá facilitar a atualização da exibição no formulário. Porque controles pertencem sempre o principal segmento de execução, qualquer chamada para um controle de um thread subordinada requer um empacotamento de chamada. O empacotamento é o ato de mover uma chamada através de limites de segmento e é muito caro em termos de recursos. Para minimizar a quantidade de empacotamento precisa ocorrer e certifique-se de que as chamadas são manipuladas de forma thread-safe, você usará o BeginInvoke para chamar métodos no thread principal de execução, minimizando a quantidade de cross-thread-limite de empacotamento que deve ocorrer. Esse tipo de chamada é necessário ao chamar métodos que manipulam os controles. Para obter mais informações, consulte Como: Manipular controles de Threads.

Para criar os procedimentos de invocar o controle

  1. Abrir o O Editor de código para frmCalculations. Na seção declarações, adicione o seguinte código.

    Public Delegate Sub FHandler(ByVal Value As Double, ByVal _
       Calculations As Double)
    Public Delegate Sub A2Handler(ByVal Value As Integer, ByVal _
       Calculations As Double)
    Public Delegate Sub LDhandler(ByVal Calculations As Double, ByVal _
       Count As Integer)
    

    Invokee BeginInvoke requerem um delegado para o método apropriado como um argumento. Essas linhas declaram o delegado assinaturas que serão usadas por BeginInvoke para chamar os métodos apropriados.

  2. Adicione os seguintes métodos de vazios para o seu código.

    Public Sub FactHandler(ByVal Factorial As Double, ByVal TotalCalculations As _
       Double)
    End Sub
    Public Sub Fact1Handler(ByVal Factorial As Double, ByVal TotalCalculations As _
       Double)
    End Sub
    Public Sub Add2Handler(ByVal Result As Integer, ByVal TotalCalculations As _
       Double)
    End Sub
    Public Sub LDoneHandler(ByVal TotalCalculations As Double, ByVal Counter As _
       Integer)
    End Sub
    
  3. Do Editar menu, use Recortar e Colar para recortar todo o código de Sub Calculator1_FactorialComplete e colá-lo em FactHandler.

  4. Repita a etapa anterior para Calculator1_FactorialMinusComplete e Fact1Handler, Calculator1_AddTwoComplete e Add2Handler, e Calculator1_LoopComplete e LDoneHandler.

    Quando terminar, não deve haver nenhum código restantes em Calculator1_FactorialComplete, Calculator1_FactorialMinusComplete, Calculator1_AddTwoComplete, e Calculator1_LoopCompletee todo o código esses usado para conter devem foram movidos para o novo apropriada de métodos.

  5. Chamar o BeginInvoke método para invocar os métodos de forma assíncrona. Você pode chamar BeginInvoke partir de um formulário (me) ou qualquer um dos controles no formulário:

    Private Sub Calculator1_FactorialComplete(ByVal Factorial As System.Double, ByVal TotalCalculations As System.Double) Handles Calculator1.FactorialComplete
       ' BeginInvoke causes asynchronous execution to begin at the address
       ' specified by the delegate. Simply put, it transfers execution of 
       ' this method back to the main thread. Any parameters required by 
       ' the method contained at the delegate are wrapped in an object and 
       ' passed. 
       Me.BeginInvoke(New FHandler(AddressOf FactHandler), New Object() _
          {Factorial, TotalCalculations })
    End Sub
    
    Private Sub Calculator1_FactorialMinusComplete(ByVal Factorial As System.Double, ByVal TotalCalculations As System.Double) Handles Calculator1.FactorialMinusComplete
       Me.BeginInvoke(New FHandler(AddressOf Fact1Handler), New Object() _
          { Factorial, TotalCalculations })
    End Sub
    
    Private Sub Calculator1_AddTwoComplete(ByVal Result As System.Int32, ByVal TotalCalculations As System.Double) Handles Calculator1.AddTwoComplete
       Me.BeginInvoke(New A2Handler(AddressOf Add2Handler), New Object() _
          { Result, TotalCalculations })
    End Sub
    
    Private Sub Calculator1_LoopComplete(ByVal TotalCalculations As System.Double, ByVal Counter As System.Int32) Handles Calculator1.LoopComplete
       Me.BeginInvoke(New LDHandler(AddressOf Ldonehandler), New Object() _
          { TotalCalculations, Counter })
    End Sub
    

    Pode parecer como se o manipulador de eventos está fazendo simplesmente uma chamada para o próximo método. O manipulador de eventos, na verdade, está causando um método a ser invocado no thread principal da operação. Essa abordagem é salva em chamadas entre os limites de thread e permite que seus aplicativos multithread executar com eficiência e sem medo de causar o travamento. Para obter detalhes sobre como trabalhar com controles em um ambiente multithread, consulte Como: Manipular controles de Threads.

  6. Salve seu trabalho.

  7. Testar sua solução, escolhendo Start Debugging partir do Debug menu.

    1. Tipo de 10000000 na caixa de texto e clique Executar o Loop de um.

      "Repetição" é exibido no rótulo abaixo deste botão. Esse loop deve levar uma quantidade significativa de tempo para ser executado. Se ele for concluído muito cedo, ajuste o tamanho do número de acordo.

    2. Em rápida sucessão, clique em todos os três botões ainda estão habilitados. Você descobrirá que todos os botões respondem à entrada. O rótulo abaixo Adicionar dois deve ser o primeiro para exibir um resultado. Resultados serão exibidos posteriormente nos rótulos sob os botões fatorial. Esses resultados avaliam infinitamente, conforme o número retornado por uma fatorial 10.000.000 é muito grande para conter uma variável de precisão dupla. Finalmente, após um atraso adicional, os resultados são retornados sob o Executar o Loop de um botão.

      Como apenas observadas, quatro conjuntos separados de cálculos foram realizados simultaneamente em quatro segmentos separados. A interface do usuário permaneceu ágil de entrada e os resultados foram retornados após cada thread concluída.

Coordenação de seus segmentos.

Um usuário experiente de aplicativos multithread pode percebê-uma sutil falha com o código como digitado. Lembre-se as linhas de código de cada sub-rotina realizar o cálculo em Calculator:

varTotalCalculations += 1
varTotalAsOfNow = varTotalCalculations

Estas duas linhas de código incrementam a variável varTotalCalculations e defina a variável de local varTotalAsOfNow a este valor. Esse valor é retornado ao frmCalculations e exibidos em um controle de rótulo. Mas está sendo retornado o valor correto? Se apenas um único segmento de execução está sendo executado, a resposta é Sim. Mas, se estiver executando vários segmentos, a resposta se torna mais indefinida. Cada segmento tem a capacidade de incrementar a variável varTotalCalculations. É possível que essa variável é incrementado após um segmento, mas antes ele copia o valor de varTotalAsOfNow, outro thread podia alterar o valor dessa variável aumentando o proprietário. Isso leva à possibilidade de que cada thread é, na verdade, relatório de resultados imprecisos. Visual Basic fornece a Instrução SyncLock para permitir a sincronização de threads para garantir que cada thread sempre retorna resultados precisos. A sintaxe para SyncLock é o seguinte:

SyncLock AnObject
   Insert code that affects the object
   Insert some more
   Insert even more
' Release the lock
End SyncLock

Quando o SyncLock bloco é inserido, a execução da expressão especificada é bloqueada até que o segmento especificado tem um bloqueio exclusivo do objeto em questão. No exemplo mostrado acima, a execução está bloqueada no AnObject. SyncLockdeve ser usado com um objeto que retorna uma referência em vez de um valor. A execução, em seguida, poderá passar como um bloco sem interferência de outros segmentos. Um conjunto de instruções que são executados como uma unidade é considerada atômica. Quando End SyncLock é encontrado, a expressão é liberada e os threads têm permissão para continuar normalmente.

Para adicionar a instrução SyncLock para seu aplicativo.

  1. Abrir Calculator.vb no O Editor de código.

  2. Localize cada instância de código a seguir:

    varTotalCalculations += 1
    varTotalAsOfNow = varTotalCalculations
    

    Deve haver quatro instâncias desse código, um em cada método de cálculo.

  3. Modificar este código para que ela seja lida da seguinte maneira:

    SyncLock Me
       varTotalCalculations += 1
       varTotalAsOfNow = varTotalCalculations
    End SyncLock
    
  4. Salve seu trabalho e testá-lo como no exemplo anterior.

    Você pode perceber um pequeno impacto no desempenho do seu programa. Isso ocorre porque a execução de threads pára quando um bloqueio exclusivo é obtido em seu componente. Embora garante a exatidão, essa abordagem impede que alguns do benefício de desempenho de vários segmentos. Cuidadosamente, você deve considerar a necessidade de threads de bloqueio e implementá-los somente quando absolutamente necessário.

Consulte também

Tarefas

Como: Coordenar vários Threads de execução

Demonstra Passo a passo: Criação de um componente Multithreaded simples com Visual C#

Referência

BackgroundWorker

Conceitos

Event-based Asynchronous Pattern Overview

Outros recursos

Programando com Componentes

Explicações Passso a Passo sobre Programação de Componentes

Multithreading em componentes