1 / 20

Bedre brugergrænseflader med multithreading

Bedre brugergrænseflader med multithreading. Captator Tlf: 8748 0202 www.captator.dk. Carsten Juel Andersen Softwarearkitekt juel@captator.dk Mobil: 2348 0003. Agenda. Hvorfor multithreading ? Multithreading i .NET Tråde, threadpool, asynkrone metodekald

Download Presentation

Bedre brugergrænseflader med multithreading

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Bedre brugergrænsefladermed multithreading Captator Tlf: 8748 0202www.captator.dk Carsten Juel Andersen Softwarearkitekt juel@captator.dk Mobil: 2348 0003 Bedre brugergrænseflader med multithreading

  2. Agenda • Hvorfor multithreading ? • Multithreading i .NET • Tråde, threadpool, asynkrone metodekald • Objekt integritet - Safety kontra liveness • Eksklusiv adgang • Synkronisering • Deadlocks • Multithreading i Window Forms UI • Single Threaded Apartment modellen • Eksempler på multithreading i Windows Forms UI • Til inspiration for hvordan multithreading kan benyttes Bedre brugergrænseflader med multithreading

  3. Hvorfor multithreading ? • Fordele • Forbedrede svartider • Simplere programdesign – hver tråd sit ”arbejdsområde” • Men der er også ulemper • Flere faldgrupper – race conditions og deadlocks • Forkert design kan forårsage de ”sjoveste” fejl(som kan være meget svære at finde) • Større ”throughput” • Få det maksimale ud af computeren • Multiprocessor maskiner, hyper threading ! Bedre brugergrænseflader med multithreading

  4. Fra single- til multithreaded applikation • Flere samtidige I/O operationer • File, netværk, webservices etc. Start tråd1 Start tråd2 Start tråd3 Afvent tråd1 Afvent tråd2 Afvent tråd3 Indlæs fil1 Indlæs fil2 Indlæs fil3 Indlæs fil1 Indlæs fil2 Indlæs fil3 Bedre brugergrænseflader med multithreading

  5. Start og join af tråde • Thread demo • Start et antal tråde og afvent at alle tråde afsluttes thread = New System.Threading.Thread(AddressOf ProcessThread) thread.Start() ... ' Afvent at tråd afslutter thread.join() ' Alternativt – afvent på tråd afslutter eller timeout If Not thread.Join(New System.TimeSpan(0, 0, 2)) Then ' Afsluttede ikke indenfor 2 sekunder End If Private Sub ProcessThread() ... End Sub Bedre brugergrænseflader med multithreading

  6. Thread pool • Thread pools er et velkendt design pattern i forbindelse med multithreading • Minimerer resourceoverheadet ved brug af tråde • .NET har en indbygget thread pool • Opretter 25 ”arbejds”-tråde første gang den benyttes Sæt arbejdsopgave1 i kø Sæt arbejdsopgave2 i kø Sæt arbejdsopgave3 i kø Afvent at de afslutter Indlæs fil1 Indlæs fil2 Indlæs fil3 Bedre brugergrænseflader med multithreading

  7. Thread pool • Thread pool demo • En tråd i thread pool afslutter ikke når ”arbejdet” er fuldført, derfor kan join ikke benyttes threadCallback = New System.Threading.WaitCallback( _AddressOf ProcessThread) System.Threading.ThreadPool.QueueUserWorkItem( _ threadCallback, fileName) ... 'Egen logik benyttes i stedet for join ' ProcessEnded er en lokal property (der ikke er vist her) While Not ProcessEnded System.Threading.Thread.Sleep(10) End If Private Sub ProcessThread(state As Object) ... _ProcessEnded = True End Sub Bedre brugergrænseflader med multithreading

  8. Asynkrone kald • Alle delegates kan kaldes asynkront • Derved afvikles delegaten på en tråd fra threadpoolen • Simplere at benytte end direkte brug af threadpoolen Public Function IndlaesTextFil( _ ByVal fileName As String) As String ... End Function IndlaesTextFil() Indlaes TextFil Delegate Opret delegate, der peger på funktionen IndlaesTextFilDelegate.Invoke() Opret delegate, der peger på funktionen IndlaesTextFilDelegate.BeginInvoke() ... IndlaesTextFilDelegate.EndInvoke() Bedre brugergrænseflader med multithreading

  9. Asynkrone kald • Asynkron delegates demo • NB: Enhver metode kan kaldes asynkront ! • ”pak metoden ind” i en delegate og kald delegaten asynkront Dim res As System.IAsyncResult ift = New IndlaesTextFilCallback(AddressOf IndlaesTextFil) ... res = ift.BeginInvoke("..\MainForm.vb", Nothing, Nothing) result = ift.EndInvoke(res) Public Delegate Function IndlaesTextFilCallback( _ ByVal fileName As String) As String Public Function IndlaesTextFil( _ ByVal fileName As String) As String ... End Function Bedre brugergrænseflader med multithreading

  10. Race conditions • En race condition kan opstå når flere tråde deler data • Uhyre simpelt eksempel • Kan det virkelig gå galt ? JA ! While True _lt.Naeste() End While Public Class LigeTal Private _tal As Integer Public Function Naeste() As Integer _tal += 1 _tal += 1 Return _tal End Function End Class While True _lt.Naeste() End While En sjælden gang imellem læses et ulige tal ! Bedre brugergrænseflader med multithreading

  11. Objekt integritet • Race conditions må ikke kunne opstå • Så betegnes systemet som ”safe” • Der kan ikke opstå race conditions, hvis der er eksklusiv adgang til alle data (en tråd af gangen) • Der er 3 måder at opnå eksklusiv adgang på • Eliminer datadeling mellem tråde • Dynamisk sikring via synkronisering • Strukturel sikring • Eksempel på strukturel:Immutable objekter - en tråd opbygger et immutable objekt, først når det er færdigbygget stilles det til rådighed for andre. • (se næste slide) • (se følgende slides) Bedre brugergrænseflader med multithreading

  12. Eliminer datadeling mellem tråde • Undgå at dele data mellem tråde • Lokale variable • valuetype parametre, variable i metoder • Thread-relative static = <ThreadStatic()> • En class/module variabel, der har en værdi for hver tråd • Thread local Storage • Thread.AllocateNamedDataSlot(”id”) Bedre brugergrænseflader med multithreading

  13. Synkronisering • Synkronisering garanterer • At kun en tråd er indenfor synkroniseringslåsens område • Andre tråde må vente udenfor synkroniseringsområdet • Ethvert objekt kan benyttes som synkroniseringslås • (dog ikke valuetypes) • C# syntaks • lock public int Naeste() { lock(this) { _tal++; _tal++; return _tal; } } Bedre brugergrænseflader med multithreading

  14. Synkronisering • VB.NET • SyncLock • Lock() / SyncLock er blot en syntaks ovenpå klassen System.Threading.Monitor • Men mere ”sikker”, fordi den garanterer balance mellem Enter og Exit monitor kald Public Function Naeste() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer Try Monitor.Enter(Me) _tal += 1 _tal += 1 Return _tal Finally Monitor.[Exit](Me) End Try End Function Bedre brugergrænseflader med multithreading

  15. ”Safe” kontra ”Liveness” • Vi kan lave en garanteret multithread ”safe” applikation • Ved at synkronisere på alt • MEN så er det på bekostning af ”Liveness” • Alle tråde bliver ”serialiserede” og performance bliver sandsynligvis endda dårligere end i en tilsvarende singlethreaded applikation • OG så ender det nok også i en Deadlock Public Class EnKlasse Public Function Foregaaende() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function End Class Public Class EnSmfrmKlasse Public Function Foregaaende() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLockMe _tal += 1 _tal += 1 Return _tal SyncLock End End Function End Clkass En anden tråd En tråd Bedre brugergrænseflader med multithreading

  16. Multithreading i Windows Forms • Windows Forms kontroller er kun beregnet til at blive afviklet på den tråd, de er oprettet af ... • ... så vi må blot sørge for at alt opdatering af kontroller foregår på den oprindelige tråd Indlæs fil1 Start tråd1 Opdater UI Bedre brugergrænseflader med multithreading

  17. Multithreading i Windows Forms • Demo af Invoke på en Windows Forms kontrol thread = New System.Threading.Thread(AddressOf ProcessThread) thread.Start() Private Sub ProcessThread() Dim fileContent As String = FileUtil.IndlaesTextFil(_fileName) _txtBox.Invoke(New UpdateTxtBoxCallback(AddressOf UpdateTxtBox), _ NewObject() {fileContent}) End Sub Private Delegate Sub UpdateTxtBoxCallback(ByVal text As String) Private Sub UpdateTxtBox(ByVal text As String) _txtBox.Text = text End Sub Bedre brugergrænseflader med multithreading

  18. Eksempel 1 – progressbar • Progress bar med cancel mulighed • F.eks. ved import / export af data, beregninger eller andre længerevarende jobs • Med mulighed for at afbryde og rulle baglæns Længerevarende Job ProcessProgressNotifier NotifyStartProcess NotifyProcessProgress NotifyEndProcess ProgressForm Cancel request Cancel request Bedre brugergrænseflader med multithreading

  19. Eksempel 2 - hurtig opstart • Applications container - en ramme for en applikation • En applikationsplugin indeholder selve funktionaliteten • Konfigurationsfil afgør hvilke plugins, der skal startes op • Loadtid for plugins kunne i princippet være meget lang <?xmlversion="1.0" encoding="utf-8"?> <configurationcomment="Configuration data for LibraEditing - Plugin data"> <configSectionname="Captator"> <configSectionname="Eifos"> <configSectionname="ApplicationContainer"> <configSetting> <name>Plugin</name> <value>LibraEditing:Captator.Eifos.Libra.Editing.DocumentPlugin</value> </configSetting> </configSection> </configSection> </configSection> ApplicationContainer Create via reflektion ApplicationsPlugin1 CreateApplicationPlugin(this) Create via reflektion ApplicationsPlugin2 CreateApplicationPlugin(this) • Ved at benytte asynkron delegate kan ApplicationContaineren tegne Formen mens de enkelte plugins loades • Resultat: Hurtig bruger feedback uanset loadtid for plugins Bedre brugergrænseflader med multithreading

  20. Spørgsmål www.captator.dknyheder, artikler, information, ... Bedre brugergrænseflader med multithreading

More Related