Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Maj 2003Bedre brugergrænseflader med multithreading1 Carsten Juel Andersen Softwarearkitekt Mobil: 2348 0003 Captator Tlf: 8748 0202

Lignende præsentationer


Præsentationer af emnet: "Maj 2003Bedre brugergrænseflader med multithreading1 Carsten Juel Andersen Softwarearkitekt Mobil: 2348 0003 Captator Tlf: 8748 0202"— Præsentationens transcript:

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

2 maj 2003Bedre brugergrænseflader med multithreading2 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

3 maj 2003Bedre brugergrænseflader med multithreading3 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 !

4 maj 2003Bedre brugergrænseflader med multithreading4 Fra single- til multithreaded applikation Flere samtidige I/O operationer File, netværk, webservices etc. Indlæs fil1 Indlæs fil2 Indlæs fil3 Indlæs fil1 Indlæs fil2 Indlæs fil3 Start tråd1 Start tråd2 Start tråd3 Afvent tråd1 Afvent tråd2 Afvent tråd3 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

5 maj 2003Bedre brugergrænseflader med multithreading5 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 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 Private Sub ProcessThread()... End Sub

6 maj 2003Bedre brugergrænseflader med multithreading6 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 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

7 maj 2003Bedre brugergrænseflader med multithreading7 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 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 Private Sub ProcessThread(state As Object)... _ProcessEnded = True End Sub

8 maj 2003Bedre brugergrænseflader med multithreading8 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 Public Function IndlaesTextFil( _ ByVal fileName As String) As String... End Function Indlaes TextFil Delegate Indlaes TextFil Delegate IndlaesTextFil() Opret delegate, der peger på funktionen IndlaesTextFilDelegate.Invoke() Opret delegate, der peger på funktionen IndlaesTextFilDelegate.Invoke() Opret delegate, der peger på funktionen IndlaesTextFilDelegate.BeginInvoke()... IndlaesTextFilDelegate.EndInvoke() Opret delegate, der peger på funktionen IndlaesTextFilDelegate.BeginInvoke()... IndlaesTextFilDelegate.EndInvoke()

9 maj 2003Bedre brugergrænseflader med multithreading9 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) 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 Delegate Function IndlaesTextFilCallback( _ ByVal fileName As String) As String Public Function IndlaesTextFil( _ ByVal fileName As String) As String... End Function Public Function IndlaesTextFil( _ ByVal fileName As String) As String... End Function

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

11 maj 2003Bedre brugergrænseflader med multithreading11 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)

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

13 maj 2003Bedre brugergrænseflader med multithreading13 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++; return _tal; } public int Naeste() { lock(this) { _tal++; return _tal; }

14 maj 2003Bedre brugergrænseflader med multithreading14 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 SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer Try Monitor.Enter(Me) _tal += 1 Return _tal Finally Monitor.[Exit](Me) End Try End Function Public Function Naeste() As Integer Try Monitor.Enter(Me) _tal += 1 Return _tal Finally Monitor.[Exit](Me) End Try End Function

15 maj 2003Bedre brugergrænseflader med multithreading15 ”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 SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function End Class Public Class EnKlasse Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function End Class Public Class EnSmfrmKlasse Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function End Clkass Public Class EnSmfrmKlasse Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function Public Function Naeste() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End Public Function Foregaaende() As Integer SyncLock Me _tal += 1 Return _tal SyncLock End End Function End Clkass En tråd En anden tråd

16 maj 2003Bedre brugergrænseflader med multithreading16 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 Start tråd1 Indlæs fil1 Opdater UI

17 maj 2003Bedre brugergrænseflader med multithreading17 Multithreading i Windows Forms Demo af Invoke på en Windows Forms kontrol thread = New System.Threading.Thread(AddressOf ProcessThread) thread.Start() 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), _ New Object() {fileContent}) End Sub Private Sub ProcessThread() Dim fileContent As String = FileUtil.IndlaesTextFil(_fileName) _txtBox.Invoke(New UpdateTxtBoxCallback(AddressOf UpdateTxtBox), _ New Object() {fileContent}) End Sub Private Sub UpdateTxtBox(ByVal text As String) _txtBox.Text = text End Sub Private Sub UpdateTxtBox(ByVal text As String) _txtBox.Text = text End Sub Private Delegate Sub UpdateTxtBoxCallback(ByVal text As String)

18 maj 2003Bedre brugergrænseflader med multithreading18 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 ProcessProgressNotifier NotifyStartProcess NotifyProcessProgress NotifyEndProcess ProcessProgressNotifier NotifyStartProcess NotifyProcessProgress NotifyEndProcess ProgressForm Længerevarende Job Cancel request

19 maj 2003Bedre brugergrænseflader med multithreading19 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 ApplicationContainer Plugin LibraEditing:Captator.Eifos.Libra.Editing.DocumentPlugin Plugin LibraEditing:Captator.Eifos.Libra.Editing.DocumentPlugin ApplicationsPlugin1 ApplicationsPlugin2 Create via reflektion CreateApplicationPlugin(this) Ved at benytte asynkron delegate kan ApplicationContaineren tegne Formen mens de enkelte plugins loades Resultat: Hurtig bruger feedback uanset loadtid for plugins

20 maj 2003Bedre brugergrænseflader med multithreading20 Spørgsmål www.captator.dk www.captator.dk nyheder, artikler, information,...


Download ppt "Maj 2003Bedre brugergrænseflader med multithreading1 Carsten Juel Andersen Softwarearkitekt Mobil: 2348 0003 Captator Tlf: 8748 0202"

Lignende præsentationer


Annoncer fra Google