Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 5 Multithreading
Pfeil 5.1 Start eines Threads
Pfeil 5.1.1 Parameterloser Start
Pfeil 5.1.2 Start mit Parameter
Pfeil 5.1.3 Hintergrundthreads
Pfeil 5.1.4 Threadeigenschaften
Pfeil 5.2 Zusammenspiel
Pfeil 5.2.1 Priorität
Pfeil 5.2.2 Warten mit Sleep
Pfeil 5.2.3 Unterbrechen mit Interrupt
Pfeil 5.2.4 Abbruch mit Abort
Pfeil 5.2.5 Warten mit Join
Pfeil 5.2.6 Warten erzwingen mit Suspend
Pfeil 5.2.7 Threadzustände
Pfeil 5.2.8 Die Klasse Thread
Pfeil 5.3 Gesicherter Datenaustausch
Pfeil 5.3.1 Objekte sperren mit Monitor
Pfeil 5.3.2 Codebereiche mit SyncLock sperren
Pfeil 5.3.3 Sperrung mit Zustand
Pfeil 5.3.4 Atomare Operationen
Pfeil 5.3.5 Attributgesteuerte Synchronisation
Pfeil 5.4 Asynchrone Methodenaufrufe
Pfeil 5.4.1 Aufruf
Pfeil 5.4.2 Rückruf
Pfeil 5.4.3 Zustand
Pfeil 5.4.4 Rückgabe
Pfeil 5.4.5 ByRef-Parameter
Pfeil 5.5 Threadpools


Rheinwerk Computing - Zum Seitenanfang

5.4 Asynchrone Methodenaufrufe Zur nächsten ÜberschriftZur vorigen Überschrift

Im Kontext dieses Kapitels können Sie eine Methode auf zwei Arten aufrufen:

  • synchron: Die Programmausführung fährt erst nach Beendigung der Methode fort.
  • asynchron: Die Methode wird gestartet, und die Programmausführung fährt (nebenläufig) fort, ohne auf das Ende der Methode zu warten.

Mit den Methoden der bisherigen Abschnitte dieses Kapitels sind wir bereits in der Lage, alle Arten von asynchronen Aufrufen zu programmieren. Im Wesentlichen lassen wir dazu eine Methode durch einen eigenen Thread starten. Damit sind aber noch nicht alle Probleme gelöst.

In den bisherigen Beispielen dieses Kapitels haben wir zwar mit verschiedenen Threads auf Daten operiert, mussten uns aber selbst darum kümmern, wann die Aktionen abgeschlossen waren. Außerdem hatten alle Methoden keinen Rückgabewert. In diesem Abschnitt zeige ich Ihnen, wie eine Methode eines anderen Threads den Aufrufer über ihren Abschluss informiert und ihm einen Wert zurückgibt.


Hinweis
Abschnitt 3.9.4, »Asynchrone Aufrufe«, zeigt im Grunde bereits den kompletten Ablauf. Ich greife das Thema bewusst ein zweites Mal auf, da es einerseits thematisch auch zu diesem Kapitel gehört und andererseits, weil ich hoffe, durch die Wiederholung auch die Programmierer zu erreichen, die asynchrone Aufrufe in eigenen Programmen vermeiden, weil sie die entsprechenden Konzepte nicht verinnerlicht haben.


In diesem Abschnitt verwenden wir als Beispiel Aufträge an das Küchenpersonal in einem Restaurant. Jemand soll den Nachtisch machen, bekommt dafür die Zutaten und kann Bescheid sagen, ob das Dessert gut geworden ist und in welchem Kühlschrank es abkühlt. Die Qualität der Arbeit wird in fünf Stufen modelliert:

  • Nachtisch wird gemacht (Aufruf).
  • Der Konditor meldet außerdem »fertig« (Rückruf).
  • Zusätzlich kennt er den Auftraggeber (Zustand).
  • Zusätzlich sagt er, wie lange er gebraucht hat (Rückgabe).
  • Zusätzlich sagt er, in welchem Kühlschrank sein Werk abkühlt (ByRef-Parameter).

Um die Beispiele einfach zu halten, sind Synchronisationsprobleme ausgeklammert.


Hinweis
Asynchrone Aufrufe nutzen den Threadpool (siehe Abschnitt 5.5, »Threadpools«).



Rheinwerk Computing - Zum Seitenanfang

5.4.1 Aufruf Zur nächsten ÜberschriftZur vorigen Überschrift

Da letztendlich immer ein Thread die asynchrone Ausführung übernimmt und diesem im Konstruktor ein passendes Delegate übergeben wird, müssen asynchrone Methodenaufrufe über ein Delegate aufgerufen werden. Wie in Abschnitt 3.9.2, »Automatisch generierter Code«, beschrieben, ist ein Delegate nichts anderes als eine Klasse, in die der Compiler automatisch zwei Methoden schreibt, die einen einfachen asynchronen Aufruf erlauben. Mit der ersten starten wir den Aufruf.


BeginInvoke(<p>, rückruf As AsyncCallback, status As Object) As IAsyncResult 
            <p>: alle Methodenparameter in der richtigen Reihenfolge


Hinweis
Das eigentlich erforderliche EndInvoke zeigt Abschnitt 5.4.4, »Rückgabe«.


Das folgende Beispiel ist der einfachste Fall eines asynchronen Aufrufs. Da wir den Wert Nothing für die beiden letzten Parameter verwenden, ist es eine Einwegekommunikation: Die Methode wird aufgerufen und dann »vergessen«.


'...\ Multitasking\Asynchron\Aufruf.vb

Option Strict On 
Imports System.Threading 
Namespace Multitasking 
  Module Aufruf

    Delegate Sub Nachtisch(ByVal zutaten As String)

    Sub Machen(ByVal zutaten As String) 
      For i As Integer = 0 To 10 
        Console.Write("|") : Thread.Sleep(10) 
      Next 
    End Sub

    Sub Test() 
      Dim del As New Nachtisch(AddressOf Machen) 
      del.BeginInvoke("Schoko", Nothing, Nothing) 
      For i As Integer = 0 To 200 
        Console.Write("-") : Thread.Sleep(10) 
      Next 
      Console.WriteLine("Arbeit abgeschlossen.") 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Eine typische Ausgabe zeigt, wie sich – nach der zum Start der asynchronen Methode Machen notwendigen Zeit – die beiden Threads abwechseln.

-------------------------------------------------------------------------- 
-------------------------|-|-||-|-|-|-|-|--|-|---------------------------- 
----------------------------------------------------------------Arbeit abg 
eschlossen.

Rheinwerk Computing - Zum Seitenanfang

5.4.2 Rückruf Zur nächsten ÜberschriftZur vorigen Überschrift

Kommen wir zur nächsten Stufe: Die aufgerufene Methode meldet sich beim Aufrufer, dass sie fertig ist. Dazu muss im AsyncCallback-Parameter eine Methode angegeben werden, die automatisch bei Beendigung der Methode aufgerufen wird. Die Signatur dieser Rückrufmethode ist festgelegt.


Public Delegate Sub AsyncCallback(ar As IAsyncResult)

In unserem Beispiel schreibt die Rückrufmethode auch in die Konsole. Zur Identifikation werden außerdem Threadnummern ausgegeben.


'...\ Multitasking\Asynchron\Rückruf.vb

Option Strict On 
Imports System.Threading 
Namespace Multitasking 
  Module Rückruf

    Delegate Sub Bescheid(ByVal zutaten As String)

    Sub Machen(ByVal zutaten As String) 
      Console.Write("Beginn in Thread {0}", _ 
                    Thread.CurrentThread.ManagedThreadId) 
      For i As Integer = 0 To 10 
        Console.Write("|") : Thread.Sleep(10) 
      Next 
      Thread.Sleep(100) 
    End Sub

    Sub Fertig(ByVal ar As IAsyncResult) 
      Console.Write("fertig in Thread {0}", _ 
                    Thread.CurrentThread.ManagedThreadId) 
    End Sub

    Sub Test() 
      Dim del As New Bescheid(AddressOf Machen) 
      Console.Write("Hauptthread {0}",Thread.CurrentThread.ManagedThreadId) 
      del.BeginInvoke("Schoko", AddressOf Fertig, Nothing) 
      For i As Integer = 0 To 200 
        Console.Write("-") : Thread.Sleep(10) 
      Next 
      Console.WriteLine("Arbeit abgeschlossen.") 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Eine typische Ausgabe zeigt, wie nach einiger Zeit die Rückmeldung erfolgt. Der Abstand zu den Ausgaben von Machen ist bedingt durch die zusätzliche Sleep-Anweisung an deren Ende. Außerdem sehen Sie, dass die Rückmeldung innerhalb des Threads der aufgerufenen Methode erfolgt, es wird also kein neuer Thread für den Rückruf erstellt.

Hauptthread 8------------------------------------------------------------- 
----------------------------------------Beginn in Thread 10|-|-|-|-|-|-|-| 
-||-|-----------fertig in Thread 10--------------------------------------- 
-----------------------------------------Arbeit abgeschlossen.

Rheinwerk Computing - Zum Seitenanfang

5.4.3 Zustand Zur nächsten ÜberschriftZur vorigen Überschrift

Die Methode BeginInvoke hat einen letzten Parameter, mit dem Sie Informationen an die Rückrufmethode durchreichen können. Welche das sind, hängt ausschließlich von der Logik Ihrer Anwendung ab. In unserem Beispiel übergeben wir nur der Einfachheit halber eine Zeichenkette.


'...\ Multitasking\Asynchron\Zustand.vb

Option Strict On 
Imports System.Threading 
Namespace Multitasking 
  Module Zustand 
    Delegate Sub Auftraggeber(ByVal zutaten As String)

    Sub Machen(ByVal zutaten As String) 
      For i As Integer = 0 To 10 
        Console.Write("|") : Thread.Sleep(10) 
      Next 
      Thread.Sleep(100) 
    End Sub

    Sub Fertig(ByVal ar As IAsyncResult) 
      Console.Write("Hallo {0}, bin fertig", ar.AsyncState) 
    End Sub

    Sub Test() 
      Dim del As New Auftraggeber(AddressOf Machen) 
      del.BeginInvoke("Schoko", AddressOf Fertig, "Paul") 
      For i As Integer = 0 To 200 
        Console.Write("-") : Thread.Sleep(10) 
      Next 
      Console.WriteLine("Arbeit abgeschlossen.") 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt die an BeginInvoke übergebene Zeichenkette:

-------------------------------------------------------------------------- 
---------------------------|-|-|-|-|-|-|-|-|-|-|----------Hallo Paul, bin 
fertig-------------------------------------------------------------------- 
------------Arbeit abgeschlossen.

Rheinwerk Computing - Zum Seitenanfang

5.4.4 Rückgabe Zur nächsten ÜberschriftZur vorigen Überschrift

Asynchrone Methoden dürfen auch einen Wert zurückgeben. Um an den Wert zu kommen, brauchen Sie das richtige Objekt vom Typ IAsyncResult: Es wird sowohl von BeginInvoke zurückgegeben als auch als Parameter an eine Rückrufmethode übergeben. Sie übergeben das Objekt der Methode EndInvoke des Delegates.


EndInvoke(<nur params mit ByRef>, ar As IAsyncResult) As <Rückgabetyp>


Hinweis

Der Aufruf blockiert gegebenenfalls so lange, bis die asynchron aufgerufene Methode fertig ist.

EndInvoke darf maximal einmal pro asynchronem Aufruf aufgerufen werden.

Der Aufruf von EndInvoke ist erforderlich, auch wenn keine Rückgabe ausgewertet wird (das exakte Warum wird im Internet kontrovers diskutiert).


Im folgenden Beispiel ist kein Parameter der asynchron aufgerufenen Methode mit ByRef gekennzeichnet, sodass EndInvoke nur mit dem letzten Argument aufgerufen wird. Der Aufruf von EndInvoke gibt den Rückgabewert der asynchron aufgerufenen Methode typrichtig zurück. Das ist einer der Gründe dafür, warum der Compiler den Code automatisch generiert und nicht eine allgemeine »Delegate-Klasse« zur Verfügung gestellt wird. Um die Ausgabe zu kürzen, testen wir in der Schleife des Hauptthreads, ob die asynchrone Methode fertig ist.


'...\ Multitasking\Asynchron\Rückgabe.vb

Option Strict On 
Imports System.Threading 
Namespace Multitasking 
  Module Rückgabe

    Delegate Function Zeit(ByVal zutaten As String) As Integer

    Function Machen(ByVal zutaten As String) As Integer 
      For i As Integer = 0 To 10 
        Console.Write("|") : Thread.Sleep(10) 
      Next 
      Thread.Sleep(100) 
      Return 200 
    End Function

    Sub Test() 
      Dim del As New Zeit(AddressOf Machen) 
      Dim ar As IAsyncResult = del.BeginInvoke("Schoko", Nothing, Nothing) 
      For i As Integer = 0 To 200 
        If ar.IsCompleted Then Exit For 
        Console.Write("-") : Thread.Sleep(10) 
      Next 
      Console.WriteLine("Zeitbedarf: {0} Minuten", del.EndInvoke(ar)) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Der Hauptthread bekommt den richtigen Rückgabewert von EndInvoke.

-------------------------------------------------------------------------- 
-----------------------|-|-|-|-|-|-|-|-||-|-----------Zeitbedarf: 200 Minu 
ten

Rheinwerk Computing - Zum Seitenanfang

5.4.5 ByRef-Parameter topZur vorigen Überschrift

Das vorige Beispiel muss nur minimal geändert werden, um auch ByRef-Parameter zu erfassen, hier ist das der kühlschrank. An welcher Stelle diese Art Parameter in der Parameterliste stehen, spielt keine Rolle. Wichtig ist, dass EndInvoke nur mit den ByRef-Parametern der asynchron aufgerufenen Methode aufgerufen wird.


'...\ Multitasking\Asynchron\Rückgabe.vb

Option Strict On 
Imports System.Threading 
Namespace Multitasking 
  Module ByRefParameter

    Delegate Sub Kühlschrank(ByRef kühlschrank As Integer, _ 
                             ByVal zutaten As String)

    Sub Machen(ByRef kühlschrank As Integer, ByVal zutaten As String) 
      For i As Integer = 0 To 10 
        Console.Write("|") : Thread.Sleep(10) 
      Next 
      Thread.Sleep(100) 
      kühlschrank = 4 
    End Sub

    Sub Test() 
      Dim ks As Integer 
      Dim del As New Kühlschrank(AddressOf Machen) 
      Dim ar As IAsyncResult = del.BeginInvoke(ks,"Schoko",Nothing,Nothing) 
      For i As Integer = 0 To 200 
        If ar.IsCompleted Then Exit For 
        Console.Write("-") : Thread.Sleep(10) 
      Next 
      del.EndInvoke(ks, ar) 
      Console.WriteLine("Kühlschrank {0}", ks) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Nach dem Aufruf von EndInvoke hat der Hauptthread den richtigen Wert.

-------------------------------------------------------------------------- 
----------------------------|-|-|-|-|-|-|-|-|-|-|----------Kühlschrank 4


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual Basic 2008
Visual Basic 2008
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Visual Basic 2012






 Visual Basic 2012


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern