İzlenecek yol: Visual Basic ile basit bir çok iş parçacıklı bileşen geliştirme
BackgroundWorker Bileşen değiştirir ve işlevsellik ekler System.Threading ad; Ancak, System.Threading ad alanı korunur geriye dönük uyumluluk ve ileride kullanmak için seçerseniz.Daha fazla bilgi için bkz. BackgroundWorker bileşenlere genel bakış.
Aynı anda birden çok görevi gerçekleştiremez uygulamaları yazabilirsiniz.Olarak adlandırılan bu beceriyi Çoklu kullanım, veya boş iş parçacığı, işlemci yoğun tasarım bileşenleri için güçlü bir araçtır ve kullanıcı girdisi iste.Neden olabilecek bir bileşen örneği kullanımını çoklu kullanım Bordro bilgilerini hesaplayan bir bileşeni olacaktır.Bileşen işlemci yoğun Bordro hesaplamaları başka birinde gerçekleştirilen iken bir veritabanına bir iş parçacığında bir kullanıcı tarafından girilen verileri işleme koyamadı.Bu işlemler ayrı bir iş parçacığı üzerinde çalıştırarak, kullanıcılar ek veri girmeden önce hesaplamaları tamamlamak için bilgisayarı bekleme gerek yoktur.Bu izlenecek yolda, aynı anda birden çok karmaşık hesaplamaları gerçekleştiren basit bir çok iş parçacıklı bileşeni oluşturur.
Projeyi Oluşturma
Uygulamanız, tek bir form ve bir bileşen oluşacaktır.Kullanıcı, değerler ve hesaplamalar başlamak için sinyal bileşenine girecektir.Formu daha sonra bileşeniniz değerleri alırsınız ve etiket denetimleri görüntüler.Bileşen işlemci yoğun hesaplamalar ve form tamamlandığında sinyal.Genel değişkenler kullanıcı arabiriminden alınan deðerleri saklamak için bileşeninizin oluşturacaktır.Bu değişkenlerin değerlerini temel alan hesaplamalar yapmak için bileşenindeki yöntemleri de gerçekleştireceksiniz.
[!NOT]
Bir işlev için bir değeri hesaplayan bir yöntemi genellikle tercih olmakla birlikte, bağımsız iş parçacıkları arasında geçirilemez, ne de değer döndürdü.Parçacıkları değerlerini sağlamak ve onlardan değerleri almak için çok basit yolu vardır.Bu gösteri genel değişkenler güncelleştirerek kullanıcı arabiriminizi deðerleri döndürecektir ve olayları bir iş parçacığı yürütmeyi tamamladığında, ana program bildirmek için kullanılır.
Gördüğünüz iletişim kutuları ve menü komutları, etkin ayarlarınıza ve ürün sürümüne bağlı olarak Yardım menüsünde açıklanana göre farklılık gösterebilir.Ayarlarınızı değiştirmek için Araçlar menüsünden İçeri ve Dışarı Aktarma Ayarları'nı seçin.Daha fazla bilgi için bkz. Visual Studio ayarları.
Form oluşturmak için
Yeni bir oluşturmak Windows Application proje.
Uygulama adı Calculations ve yeniden adlandırma Form1.vb olarak frmCalculations.vb.
Ne zaman Visual Studio sizden yeniden adlandırmak için Form1 kod öğesi,'ı Evet.
Bu formu, uygulamanız için birincil kullanıcı arabirimi olarak hizmet verecektir.
Beş ekleme Label denetler, dört Button kontrol eder ve bir TextBox Formunuza denetim.
Denetim
Ad
Text
Label1
lblFactorial1
(boş)
Label2
lblFactorial2
(boş)
Label3
lblAddTwo
(boş)
Label4
lblRunLoops
(boş)
Label5
lblTotalCalculations
(boş)
Button1
btnFactorial1
Çarpınımı
Button2
btnFactorial2
Çarpınımı - 1
Button3
btnAddTwo
İki ekleme
Button4
btnRunLoops
Bir döngü çalıştırın
TextBox1
txtValue
(boş)
Hesap Makinesi bileşen oluşturmak için
Dan Proje menüsünde, select Bileşen ekleme.
Bu bileşen ad Calculator.
Genel değişkenler için hesap makinesi bileşen eklemek için
Açık Kod Düzenleyicisi'ni için Calculator.
Değerleri geçirmek için kullanılacak ortak değişkenleri oluşturmak için ifadeleri ekleyin frmCalculations her iş parçacığı için.
Değişken varTotalCalculations hesaplamalar toplam sayısının toplamı bileşeni ve diğer değişkenler tarafından gerçekleştirilen Canlı değerlerini formdan alacak.
Public varAddTwo As Integer Public varFact1 As Integer Public varFact2 As Integer Public varLoopValue As Integer Public varTotalCalculations As Double = 0
Hesap Makinesi bileşen yöntemlerini ve olaylarını eklemek için
Bileþeniniz formunuza değerler iletişim kurmak için kullanacağı olayları bildirmek.Hemen önceki adımda girilen değişken bildirimlerini altında aşağıdaki kodu yazın:
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)
1. Adımda girilen değişken bildirimlerini hemen aşağıdaki kodu yazın:
' 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
Bileşen için kullanıcı girişi aktarılıyor
Sonraki adım kodu eklemektir frmCalculations kullanıcıdan girdi almak ve aktarmak ve birinden diğerine değerleri almak için Calculator bileşeni.
FrmCalculations için ön uç işlevselliğini uygulamak için
Seçin Build Solution karşı Build menüsü.
Windows Form Tasarımcısında frmCalculations'i açın.
Bulun Hesaplamalar bileşenleri sekmesinde araç.Sürükle bir Hesap Makinesi bileşen tasarım yüzeyi üzerine.
İçinde özellikleri 'ı, windows olayları düğme.
Her olay işleyicileri oluşturmak için dört olayları çift frmCalculations.Her olay işleyicisi oluşturduktan sonra Tasarımcısı dönmek gerekecek.
Formunuzu alma olayları işlemek için aşağıdaki kodu ekleyin 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
Bulun End Class deyiminin sonuna Kod Düzenleyicisi'ni.Hemen onu düğmesini tıkladığında işlemek için aşağıdaki kodu ekleyin:
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
Uygulamanızı test etme
Şimdi bir bileşeni çeşitli karmaşık hesaplamalar gerçekleştirebilir ve biçimi içeren bir proje oluşturduk.Yine de çoklu kullanım yeteneği kaydettirmeyen henüz devam etmeden önce işlevselliğini doğrulamak için projenizi sınayacak.
Projenizi sınamak için
Dan Debug menüsünden seçin Start Debugging komutunu.Uygulama başlar ve frmCalculations görünür.
Metin kutusuna 4, etiketli düğmesini tıklatıp Eklemek iki.
"6" Rakamı altındaki etiket görüntüleneceğini ve "Toplam hesaplamaları are 1" görüntüleneceğini lblTotalCalculations.
Şimdi etiketli düğmeyi çarpınımı - 1.
"6" Rakamı düğmesini görüntülenmesi gerektiğini ve lblTotalCalculations şimdi "toplam hesaplamaları olan 4."
Metin kutusu değerini değiştirmek 20, etiketli düğmesini tıklatıp çarpınımı.
Bunun "2.43290200817664E + 18" numarası görüntülenir ve lblTotalCalculations şimdi "Toplam hesaplamaları var. 24" okur
Metin kutusu değerini değiştirmek 50000'den, etiketli düğmeyi tıklatıp ardından Çalışacak bir döngü.
Bu düğmeyi yeniden etkinleştirildi önce küçük, ancak dikkat çekici bir aralığı olduğunu unutmayın.Bu düğme altında etiket "50000'den" okumalısınız ve görüntülenen toplam hesaplamaları olan "25000024"
Metin kutusu değerini değiştirmek 5000000 ve etiketli düğmeyi tıklatın Çalışacak bir döngü, hemen etiketli düğmeyi tıklatın Eklemek iki.' I Eklemek iki yeniden.
Düğme yanıt vermiyor, ne de herhangi bir denetimi form üzerinde döngüler tamamlanıncaya kadar yanıt verir.
Yalnızca tek bir iş parçacığı yürütme programınız çalışıyorsa, yukarıdaki örnekteki gibi işlemci yoğun hesaplamalar hesaplamaları tamamlayıncaya kadar programı tedariği birbirine bağlamanın eğilimi vardır.Sonraki bölümde, birden çok iş parçacığı aynı anda çalışacak şekilde uygulamanıza çoklu kullanım yeteneği ekleyeceksiniz.
Çoklu kullanım özelliği ekleme
Önceki örnekte, yalnızca tek bir iş parçacığı yürütme çalıştırılan uygulamaların sınırlamalarını gösterilmektedir.Sonraki bölümde kullanacağınız Thread birden çok iş parçacığı yürütme, bileşen eklemek için sınıf.
İş parçacığı altyordamını eklemek için
Açık Calculator.vb , Kod Düzenleyicisi'ni.Üst kodunun bulun Public Class Calculator satır.Hemen onu altında aşağıdakini yazın:
' 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
Hemen önce End Class kod alt ifadeyi aşağıdaki yöntemi ekleyin:
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
Zaman bir Thread nesne örneği, şeklindeki bir bağımsız değişken gerektiren bir ThreadStart nesnesi.ThreadStart Burada başlamak için iş parçacığı, altyordam adresine işaret eden temsilci nesnesidir.A ThreadStart nesne parametreleri veya geçişi değerleri alınamıyor ve böylece bir işlev belirtin olamaz.AddressOf işleci (Visual Basic) İşlevi gören bir temsilci ThreadStart nesnesi.ChooseThreads Sub yalnızca uygulanan onu çağıran programdan bir değer alması ve başlatmak için uygun iş parçacığı belirlemek için bu değeri kullanın.
FrmCalculations için iş parçacığı başlatma kodu eklemek için
Açık frmCalculations.vb , dosya Kod Düzenleyicisi'ni.Locate Sub btnFactorial1_Click.
Çağıran satırı altyordamýndaki Calculator1.Factorialdoğrudan gösterildii gibi yöntemi:
' Calculator1.Factorial
Aramak için aşağıdaki satırı ekleyin Calculator1.ChooseThreads yöntemi:
' Passes the value 1 to Calculator1, thus directing it to start the ' correct thread. Calculator1.ChooseThreads(1)
Benzer diğer değişiklikler button_click çağırılacakları.
[!NOT]
Uygun değer içerdiğinden emin olun threads bağımsız değişkeni.
Bitirdiğinizde, kod aşağıdaki gibi görünmelidir:
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
Denetimleri çağrıları sıralaması
Şimdi, formu ekranda güncelleme salayacaktır.Denetimler her zaman ana yürütme iş parçacığı tarafından sahipliğinde olduğundan herhangi bir çağrısından bir denetime bağımlı iş parçacığının gerektiren bir sıralama çağırın.Sıralama, iş parçacığı sınırlarında bir çağrı taşıma işlemidir ve kaynaklar oldukça maliyetlidir.Oluşur ve aramalarınız iş parçacığı için güvenli bir biçimde işlediğinden emin olmak için gereken sıralaması miktarını en aza indirmek için kullanacağınız BeginInvoke ana iş parçacığında yürütme yöntemlerini çağırmak için böylece çapraz-iş parçacığı-sınır, sıralama miktarını en aza indirme gerçekleşmelidir.Bu tür bir çağrı denetimlerini işleme yöntemi çağrılırken gereklidir.Daha fazla bilgi için bkz. Nasıl yapılır: iş parçacığı denetimlerden işlemek.
Denetim yürütmesini yordamları oluşturmak için
Açık Kod Düzenleyicisi'ni için frmCalculations.Tanımlamalar bölümüne aşağıdaki kodu ekleyin.
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)
Invokeve BeginInvoke uygun yönteme bir bağımsız değişken olarak bir temsilci gerektirir.Bu satırlar tarafından kullanılan imzalar temsilcinin bildirmek BeginInvoke uygun yöntemleri çağırmak için.
Aşağıdaki boş yöntemler kodunuzu ekleyin.
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
Dan düzenleme kullan menüsünden Kes ve yapıştırın koddan kesmek için Sub Calculator1_FactorialComplete ve içine yapıştırın FactHandler.
Repeat the previous step for Calculator1_FactorialMinusComplete and Fact1Handler, Calculator1_AddTwoComplete and Add2Handler, and Calculator1_LoopComplete and LDoneHandler.
Bitirdiğinizde, kod içinde kalan olmalıdır Calculator1_FactorialComplete, Calculator1_FactorialMinusComplete, Calculator1_AddTwoComplete, ve Calculator1_LoopCompleteve bunlar içermek için kullanılan taşınır uygun yeni yöntemler için kod.
Call BeginInvoke zaman uyumsuz olarak yöntemlerini çağırmak için yöntem.Arayabileceğiniz BeginInvoke da formunuzu (me) veya herhangi bir form üzerindeki denetimleri:
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
Olay işleyicisi basitçe sonraki yöntemine yapılan bir çağrı yapma gibi olsa da görünebilir.Olay işleyicisi işlemi ana iş parçacığı üzerinde çağrılacak yöntemi aslında neden oluyor.Bu yaklaşım, iş parçacığı sınırlarında çağrılarda kaydeder ve verimli ve kilitlenmesine neden olan Korku olmadan çalıştırmak, çok iş parçacıklı uygulamalar sağlar.Çok iş parçacıklı ortamda denetimleri ile çalışma hakkında daha fazla bilgi için bkz: Nasıl yapılır: iş parçacığı denetimlerden işlemek.
Çalışmanızı kaydedin.
Seçerek çözümünüzü deneyin Start Debugging komutunu karşı Debug menüsü.
Type 10000000 tıklatın ve metin kutusu içindeki Çalışacak bir döngü.
Bu düğmenin altındaki etikette "Döngü" görüntülenir.Bu döngü, önemli ölçüde çalıştırılacak zaman almanız gerekir.Çok erken tamamlarsa, sayının boyutuna uygun şekilde ayarlayın.
Art arda hızlı biçimde, halen etkin olan tüm üç düğmelerini tıklatın.Tüm düğmeleri iletilerinizi ºu adrese yanıt bulacaksınız.Altındaki etikette Eklemek iki bir sonucu görüntülemek için ilk olmalıdır.Sonuçlar daha sonra etiketlerde Faktöriyel düğmeleri altında görüntülenir.10,000,000 Çarpınımı tarafından döndürülen sayı bir çift duyarlıklı değişken içeren çok büyük olduğu gibi bu sonuçlar sonsuza kadar değerlendirin.Son olarak, ek bir gecikmeden sonra sonuçları altında döndürülen Çalışacak bir döngü düğme.
Yalnızca gözlenen gibi dört ayrı bir kümesi hesaplamaları aynı anda dört ayrı iş parçacıkları gerçekleştirilmiştir.Kullanıcı arabirimi giriş tepki olarak kalır ve tamamlanan her iş parçacığı sonra sonuç döndürülmedi.
Kendi iş parçacığı koordine
Çok iş parçacıklı uygulamalarda deneyimli kullanıcı koduyla yazılan ince bir kusur düşünebilir.Her hesaplamayı gerçekleştirmeden alt yordam içinde kod satırları geri çağırmak Calculator:
varTotalCalculations += 1
varTotalAsOfNow = varTotalCalculations
Bu iki kod satırı ortak deðiþkenini artýrmak varTotalCalculations ve yerel değişken varTotalAsOfNow için bu değeri.Bu değer daha sonra döndürülen frmCalculations ve bir label denetimi görüntülenir.Ancak, doğru değer verdi?Yalnızca tek bir yürütme iş parçacığı çalışıyor, açıkça yanıttır Evet.Ancak, birden çok iş parçacığı çalıştırıyorsanız, yanıt daha belirsiz hale gelir.Her iş parçacığı deðiþkenini artýrmak gönderebilen varTotalCalculations.Bu değişken artırır, bir iş parçacığının sonra mümkün olduğu halde önce onu kopyalar değeri varTotalAsOfNow, başka bir iş parçacığı bu değişkenin değerini artırma ile değiştirecek.Bu her iş parçacığı tutarsız sonuçlar aslında raporlama olasılık yol açar.Visual Basic sağlar SyncLock deyimi her iş parçacığı her zaman doğru sonuç verir emin olmak için iş parçacıkları eşitlemeye izin vermek için.Sözdizimi SyncLock aşağıdaki gibidir:
SyncLock AnObject
Insert code that affects the object
Insert some more
Insert even more
' Release the lock
End SyncLock
Zaman SyncLock blok girilir, söz konusu nesne üzerinde özel kilit belirtilen iş parçacığı sahip olana kadar üzerinde belirtilen deyim yürütme engellendi.Yukarıda gösterilen örnekte, yürütme engellendi AnObject.SyncLockbir değer yerine, bir başvuru veren bir nesne ile kullanılması gerekir.Yürütme sonra bloğu hiçbir kesinti olmadan devam edebilirsiniz.Bir birim olarak execute deyimleri kümesini olmasını söyledi Atomik.Zaman End SyncLock olan karşılaştı, ve ifade serbest iş parçacığı normal olarak devam etmek için izin verilir.
Uygulamanıza SyncLock'deyimi eklemek için
Açık Calculator.vb , Kod Düzenleyicisi'ni.
Her bir örneği aşağıdaki kodu bulun:
varTotalCalculations += 1 varTotalAsOfNow = varTotalCalculations
Bu kod, hesaplama yöntemi her birinde dört örneklerini olması gerekir.
Bu kodu aşağıdaki gibi değiştirin:
SyncLock Me varTotalCalculations += 1 varTotalAsOfNow = varTotalCalculations End SyncLock
Çalışmanızı kaydedin ve önceki örnekte olduğu gibi test edin.
Programınızın performansını hafif bir etkisi olduğunu fark edebilirsiniz.Bileþeniniz üzerinde özel kilit alındığında yürütme iş parçacığı durdurulur olmasıdır.Doğruluk sağlar, ancak bu yaklaşım bazı birden çok iş parçacığı performans avantajı impedes.Dikkatle kilitleme iş parçacığı gereğini göz önünde bulundurun ve bunları yalnızca kesinlikle gerekli olduğunda uygulamak gerekir.
Ayrıca bkz.
Görevler
Nasıl yapılır: birden çok iş parçacığı yürütme eşgüdümlemek
İzlenecek yol: Visual C# ile basit bir çok iş parçacıklı bileşen geliştirme
Başvuru
Kavramlar
Olay tabanlı zaman uyumsuz desen genel bakış