Wskazówki: tworzenie prostego składnika wielowątkowego za pomocą języka Visual Basic
BackgroundWorker Składnika zastępuje i dodaje funkcje do System.Threading nazw; Jednakże System.Threading obszaru nazw jest zachowywana zarówno dla zgodności z poprzednimi wersjami i wykorzystania w przyszłości, jeśli wybierzesz.Aby uzyskać więcej informacji, zobacz BackgroundWorker — Informacje o składniku.
Można napisać aplikacje, które są zdolne do wykonywania wielu zadań jednocześnie.Ta możliwość o nazwie wielowątkowości, lub wolnych wątków, jest wygodnym sposobem projektowania składników, które procesor i wymagają danych wejściowych użytkownika.Wykorzystanie przykład składnika, który może spowodować, że wielowątkowość byłoby składnik, który oblicza informacje listy płac.Składnik może przetwarzać dane wprowadzone do bazy danych przez użytkownika na jeden wątek podczas obliczania listy płac procesor były wykonywane w innym.Uruchamiając te procesy osobne wątki, użytkownicy nie muszą czekać na komputerze do wykonania obliczeń przed wprowadzeniem dodatkowych danych.W tym instruktażu utworzy prosty składnik wielowątkowe, który wykonuje jednocześnie wiele złożonych obliczeń.
Tworzenie projektu
Aplikacja składa się z jednego formularza i składnika.Użytkownika będą wprowadzane wartości i sygnał rozpoczęcia obliczeń do składnika.Formularz będzie następnie otrzymywać wartości składnika i wyświetlić je w formantów etykiet.Składnik będzie wykonywać obliczenia procesor i sygnału formularza po zakończeniu.Zmienne publiczne utworzy w składniku do przechowywania wartości otrzymanych od interfejsu użytkownika.Będzie także implementować metody w składniku wykonywać obliczenia na podstawie wartości tych zmiennych.
[!UWAGA]
Gdy funkcja jest zazwyczaj wygodniej dla metody, która oblicza wartość, argumenty nie mogą być przekazywane między wątki ani mogą być zwracane wartości.Wiele sposobów proste do dostarczania wartości wątków oraz otrzymują od ich wartości.W tej demonstracji poprzez aktualizację zmiennych publicznych zwróci wartości do interfejsu użytkownika i zdarzenia będą używane do powiadamiania głównego programu po zakończeniu wykonywania wątku.
Okna dialogowe i polecenia menu może być różnią się od opisane w pomocy w zależności od ustawień aktywny lub edition.Aby zmienić ustawienia, wybierz polecenie Ustawienia eksportu i importu na Narzędzia menu.Aby uzyskać więcej informacji, zobacz Dostosowywanie ustawień środowiska deweloperskiego w Visual Studio.
Aby utworzyć formularz
Utwórz nowy Aplikacji Windows projektu.
Nazwa aplikacji Calculations i zmień nazwę Form1.vb jako frmCalculations.vb.
Gdy pojawi się monit o Zmień nazwę Visual Studio Form1 kod elementu, kliknij przycisk Tak.
Ten formularz będzie służyć jako podstawowy interfejs aplikacji.
Dodać pięć Label kontroluje cztery Button formanty i jednego TextBox formantu do formularza.
Formant
Nazwa
Tekst
Label1
lblFactorial1
(puste)
Label2
lblFactorial2
(puste)
Label3
lblAddTwo
(puste)
Label4
lblRunLoops
(puste)
Label5
lblTotalCalculations
(puste)
Button1
btnFactorial1
Silnia
Button2
btnFactorial2
Silnia - 1
Button3
btnAddTwo
Dodać dwie
Button4
btnRunLoops
Uruchom pętli
TextBox1
txtValue
(puste)
Aby utworzyć składnik kalkulatora
Z projektu menu wybierz Dodać składnik.
Nazwa tego składnika Calculator.
Aby dodać zmiennych publicznych do składnika kalkulatora
Otwórz Edytor kodu dla Calculator.
Dodać instrukcje do tworzenia zmiennych publicznych, które będą używane do przekazania wartości z frmCalculations do każdego wątku.
Zmienna varTotalCalculations będzie Zachowaj sumy całkowitej liczby obliczenia wykonywane przez składnik i inne zmienne otrzymają wartości z formularza.
Public varAddTwo As Integer Public varFact1 As Integer Public varFact2 As Integer Public varLoopValue As Integer Public varTotalCalculations As Double = 0
Aby dodać metod i zdarzeń do składnika kalkulatora
Zadeklarować zdarzenia, które składnik będą używać do komunikowania się wartości do formularza.Bezpośrednio pod deklaracjami zmiennych w poprzednim kroku, wpisz następujący kod:
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)
Bezpośrednio pod deklaracjami zmiennych w kroku 1, wpisz następujący kod:
' 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
Transferowanie danych wejściowych użytkownika do składnika
Następnym krokiem jest dodanie kodu do frmCalculations do odbierania danych wejściowych od użytkownika oraz do transferu i otrzymują wartości do i z Calculator składnika.
Aby zaimplementować frontonu funkcji frmCalculations
Wybierz Roztwór budować z budować menu.
Otwórz frmCalculations Windows Forms projektanta.
Zlokalizuj Składniki obliczenia kartę w Przybornik.Przeciągnij Kalkulator składnik na powierzchnię projektu.
W Właściwości systemu windows, kliknij zdarzenia przycisku.
Kliknij dwukrotnie każde z czterech zdarzeń do tworzenia zdarzeń w frmCalculations.Należy powrócić do projektanta po utworzeniu każdego programu obsługi zdarzeń.
Wstaw następujący kod do obsługi zdarzenia formularza będzie otrzymywać od 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
Zlokalizuj End Class instrukcji na dole Edytor kodu.Bezpośrednio nad nim, Dodaj następujący kod do obsługi kliknięcia przycisku:
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
Testowanie aplikacji
Tworzony projekt formularza i składnik zdolny do kilku złożonych obliczeń.Chociaż nie wprowadziły wielowątkowości możliwości jeszcze, będzie badanie projektu sprawdzić jego funkcjonalności, przed kontynuowaniem.
Aby przetestować projekt
Z debugowania menu wybierz Uruchomić debugowanie.Aplikacja zaczyna i frmCalculations pojawi się.
W polu tekstowym wpisz 4, następnie kliknij przycisk o nazwie Dodać dwa.
Cyfrę "6" powinien być wyświetlany w etykiecie poniżej i "1 są obliczenia całkowitej" powinien być wyświetlany w lblTotalCalculations.
Teraz kliknij przycisk o nazwie silnia - 1.
Cyfrę "6" powinien być wyświetlany poniżej przycisku i lblTotalCalculations teraz odczytuje "Są obliczenia całkowitej 4."
Zmień wartość w polu tekstowym, aby 20, następnie kliknij przycisk o nazwie silnia.
Poniżej, jest wyświetlany numer "2.43290200817664E + 18" i lblTotalCalculations teraz odczytuje "Sumy są 24."
Zmień wartość w polu tekstowym 50000, a następnie kliknij przycisk oznaczony Uruchomić pętli a.
Uwaga jest niewielki, ale zauważalne interwał przed tego przycisku zostanie ponownie włączony.Etykieta przycisku tego należy przeczytać "50000" i obliczania sum, wyświetlane są "25000024".
Zmień wartość w polu tekstowym, aby 5000000 i kliknij przycisk z etykietą Uruchomić pętli ai natychmiast kliknij przycisk z etykietą Dodać dwa.Kliknij Dodać dwa ponownie.
Przycisk nie odpowie, ani formantu w formularzu odpowie zakończenia pętli.
Uruchomienie programu jednym wątku wykonywania obliczeń procesor, jak w powyższym przykładzie mają tendencję do blokuje program, do momentu zakończenia obliczeń.W następnej sekcji zostaną dodane wielowątkowości zdolności do aplikacji tak, aby wiele wątków może uruchomić jednocześnie.
Dodanie możliwości wielowątkowość
Poprzedni przykład wykazać ograniczenia aplikacje uruchamiane w jednym wątku wykonywania.W następnej sekcji będzie używać Thread klasy, aby dodać wiele wątków wykonanie do składnika.
Aby dodać podprocedury wątków
Otwórz Calculator.vb w Edytor kodu.W górnej części kodu zlokalizować Public Class Calculator linii.Bezpośrednio pod nim, należy wpisać:
' 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
Bezpośrednio przed End Class instrukcji w dolnej części kodu, dodaj następującą metodę:
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
Gdy Thread tworzyć wystąpień obiektu, wymaga argumentu w postaci ThreadStart obiektu.ThreadStart Obiekt jest pełnomocnika, który wskazuje adres podprocedurę, gdzie ma rozpocząć wątku.A ThreadStart obiekt nie może mieć parametrów lub przebiegu, wartości i nie może zatem wskazują funkcję.AddressOf — Operator (Visual Basic) Zwraca pełnomocnika, który służy jako ThreadStart obiektu.ChooseThreads Sub właśnie zaimplementowanej otrzymają wartości z programu to wywołanie i wartości można używać do określenia odpowiedniego wątku, aby uruchomić.
Aby dodać kod uruchomienie wątku frmCalculations
Otwórz frmCalculations.vb pliku w Edytor kodu.Locate Sub btnFactorial1_Click.
Komentarz linii, który wywołuje Calculator1.Factorialmetoda bezpośrednio, jak pokazano:
' Calculator1.Factorial
Dodaj następujący wiersz do wywołania Calculator1.ChooseThreads metody:
' Passes the value 1 to Calculator1, thus directing it to start the ' correct thread. Calculator1.ChooseThreads(1)
Wprowadzić zmiany podobne do drugiej button_click podprocedury.
[!UWAGA]
Należy uwzględnić odpowiednią wartość dla threads argumentu.
Po zakończeniu, kod powinno wyglądać podobnie do następującego:
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
Kierowanie połączeń do formantów
Teraz ułatwi aktualizacją wyświetlania w formularzu.Ponieważ formanty są zawsze własnością głównego wątku wykonywania, każde wywołanie formantu z wątku podrzędnego wymaga kierowanie wywołania.Kierowanie jest aktem przenoszenia wywołania przez granice wątków i jest bardzo kosztowne w odniesieniu do zasobów.Aby zminimalizować ilość kierowanie musi wystąpić i w sposób bezpieczny wątek obsługi wywołania upewnij się, będą używać BeginInvoke do wywołania metody w głównym wątku wykonanie, zminimalizować ilość wątku transgraniczny, kierowanie musi wystąpić.Konieczne jest wywołanie tego rodzaju podczas wywoływania metody manipulujące formantów.Aby uzyskać więcej informacji, zobacz Porady: manipulowanie kontrolkami pochodzącymi z wątków.
Aby utworzyć wywoływanie kontroli procedury
Otwórz Edytor kodu dla frmCalculations.W sekcji deklaracji Dodaj następujący kod.
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)
Invokei BeginInvoke wymagają pełnomocnika do odpowiedniej metody jako argumentu.Te wiersze zadeklarować pełnomocnika podpisy, które będą używane przez BeginInvoke do wywołania właściwych metod.
Dodaj następujące metody pusty do kodu.
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
Z Edytuj menu Użyj Wytnij i Wklej do wycinania kod z Sub Calculator1_FactorialComplete i wklej go do FactHandler.
Repeat the previous step for Calculator1_FactorialMinusComplete and Fact1Handler, Calculator1_AddTwoComplete and Add2Handler, and Calculator1_LoopComplete and LDoneHandler.
Po zakończeniu powinny być żadnego kodu pozostające w Calculator1_FactorialComplete, Calculator1_FactorialMinusComplete, Calculator1_AddTwoComplete, i Calculator1_LoopCompletei wszystkie te powinien zawierać powinno zostały przeniesione do odpowiednich nowych metod kodu.
Wywołanie BeginInvoke metody do wywołania metody asynchronicznie.Można wywołać BeginInvoke z jednego formularza (me) lub formantów formularza:
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
Może ona wydawać, że obsługi zdarzeń jest po prostu nawiązywania połączenia do następnej metody.Metoda powoływać się w głównym wątku operacji faktycznie powoduje obsługi zdarzeń.Podejście to zapisuje na wywołania przez granice wątków i pozwala skutecznie i bez obawy powoduje blokowanie aplikacji wielowątkowych.Szczegółowe informacje dotyczące pracy z formantów w środowisku wielowątkowym Porady: manipulowanie kontrolkami pochodzącymi z wątków.
Zapisz swoją pracę.
Sprawdź swoje rozwiązanie, wybierając Uruchomić debugowanie z debugowania menu.
Typ 10000000 w polu tekstowym i kliknij Uruchomić pętli a.
"Pętli" jest wyświetlany w etykiecie poniżej tego przycisku.Ta pętla powinny podjąć znaczną ilość czasu na uruchomienie.Wykona on zbyt wcześnie, należy odpowiednio dostosować rozmiar liczby.
W krótkim odstępie czasu kliknij wszystkie trzy przyciski, które są nadal włączone.Znajdziesz, że wszystkie przyciski odpowiadać na dane wejściowe.Etykieta pod Dodać dwa powinny być najpierw do wyświetlenia wyniku.Wyniki wyświetlane są później w etykietach poniżej przycisków silni.Te wyniki oceny do nieskończoności, jako liczba zwracanych przez 10 000 000 silnia jest zbyt duży dla zmiennej podwójnej precyzji zawierają.Wreszcie, opóźnieniem dodatkowe wyniki są zwracane pod Uruchomić pętli a przycisku.
Po prostu obserwowane, czterech oddzielnych zestawów obliczenia były wykonywane jednocześnie na czterech oddzielnych wątków.Interfejs użytkownika pozostała odpowiadać wejściowe i wyniki zostały zwrócone po każdego wątku zakończone.
Koordynowanie wątkom
Doświadczonych użytkowników, aplikacji wielowątkowych mogą postrzegać subtelnych usterka kod wpisanych.Odwołaj wiersze kodu pochodzące z każdego programowego wykonywania obliczeń w Calculator:
varTotalCalculations += 1
varTotalAsOfNow = varTotalCalculations
Te dwa wiersze kodu, zwiększ wartość zmiennej publicznej varTotalCalculations i zmienna lokalna varTotalAsOfNow tej wartości.Ta wartość jest zwracany do frmCalculations i wyświetlane w formancie etykiety.Ale jest zwracany poprawny?Jeśli tylko pojedynczego wątku wykonywania jest uruchomiony, odpowiedź jest wyraźnie tak.Ale jeśli korzystasz z wielu wątków, odpowiedź staje się bardziej niepewna.Każdy wątek ma możliwość Zwiększ wartość zmiennej varTotalCalculations.Możliwe, że po jednym wątku zwiększa tej zmiennej, ale przed kopiuje wartość varTotalAsOfNow, inny wątek może zmienić wartość tej zmiennej, zwiększając ją.Prowadzi to możliwość, że każdy wątek w rzeczywistości raportowania niedokładnych wyników.Visual Basic zapewnia SyncLock — Instrukcja , aby umożliwić synchronizacji wątków, aby zapewnić, że każdy wątek ma zawsze zwraca dokładny wynik.Składnia SyncLock jest następujący:
SyncLock AnObject
Insert code that affects the object
Insert some more
Insert even more
' Release the lock
End SyncLock
Gdy SyncLock jest wprowadzana w bloku, wykonanie na określone wyrażenie jest zablokowana, dopóki określony wątek ma wyłączną blokadę na dany obiekt.W powyższym przykładzie wykonywanie jest zablokowany na AnObject.SyncLockmusi być używana z obiektu, który zwraca odwołanie niż wartość.Następnie kontynuować wykonywanie jako blok bez zakłóceń z innych wątków.Zestaw instrukcji, które wykonywane jako jednostka są określane jako atomic.Gdy End SyncLock jest napotkał, wyrażenie jest zwalniany i wątki mogą kontynuować normalnie.
Aby dodać instrukcję SyncLock do aplikacji
Otwórz Calculator.vb w Edytor kodu.
Zlokalizuj każde wystąpienie następujący kod:
varTotalCalculations += 1 varTotalAsOfNow = varTotalCalculations
Powinny być cztery wystąpienia tego kodu, jeden w każdej metodzie obliczeń.
Zmodyfikować ten kod, tak aby otrzymuje brzmienie:
SyncLock Me varTotalCalculations += 1 varTotalAsOfNow = varTotalCalculations End SyncLock
Zapisz swoją pracę i przetestować w poprzednim przykładzie.
Można zauważyć niewielki wpływ na wydajność programu.Jest to spowodowane uzyskiwane są wyłączną blokadę na składnik przerywa wykonywanie wątków.Chociaż zapewnia dokładność, podejście to utrudnia niektóre korzyści wydajności wiele wątków.Należy uważnie rozważyć potrzebę blokowania wątków i je tylko wtedy, gdy jest to absolutnie konieczne.
Zobacz też
Zadania
Porady: koordynowanie wielu wątków wykonania
Wskazówki: tworzenie prostego składnika wielowątkowego za pomocą języka C#
Informacje
Koncepcje
Asynchroniczny wzorzec oparty na zdarzeniach — przegląd
Inne zasoby
Programowanie przy użyciu składników