ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 10.01.2001

Diese Seite wurde zuletzt aktualisiert am 10.01.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Threads asynchron starten

Zurück...


Anzeige

(-hg) mailto:hg_callasync@aboutvb.de

Sie können eine ActiveX-EXE-Komponente eine eigene Aufgabe unabhängig von Ihrer eigenen Anwendung und parallel im Hintergrund ausführen lassen - in einem eigenen Thread. Damit jedoch Ihre Anwendung nach dem Aufruf dieser Komponente nicht blockiert ist und wartet, bis diese ihre Aufgabe erledigt hat, müssen Sie den Aufruf entkoppeln (ein so genannter "asynchroner" Aufruf).

In der Komponente halten Sie dazu die eventuell mit dem Start-Aufruf als Parameter übergebenen Daten fest und initiieren zunächst nur einen Mechanismus, der für eine spätere Ausführung der gewünschten Aufgabe mit den übergebenen Daten sorgt. Der Start-Aufruf wäre damit beendet, so dass der diesem Aufruf nachfolgende Code in der Client-Anwendung weiter ausgeführt wird.

Dieser besagte Mechanismus in der Komponente, der sich um die verzögerte Bearbeitung der Aufgabe kümmert, ist ein Timer-Steuerelement. Standardmäßig ist dieser Timer deaktiviert. Die Initiierung des verzögernden Mechanismus besteht nun lediglich darin, diesen Timer zu aktivieren (Enabled = True). Der Interval-Wert des Timers kann beliebig kurz sein, so dass im eigentlichen Sinne gar keine Verzögerung entsteht. Es geht nur darum, dass der Timer sein erstes Ereignis erst auslöst, nachdem die Start-Methode vollständig abgearbeitet worden ist. Wichtig ist nur, dass in diesem Start-Ereignis der Timer sofort wieder deaktiviert wird und das Timer-Ereignis nur ein einzige Mal ausgelöst wird.

Das Form, auf dem der Timer platziert ist, kann unsichtbar bleiben. Es kann aber auch angezeigt werden und beispielsweise eine Fortschrittanzeige enthalten. Von diesem Form muss für die Verbindungsklasse eine eigene Instanz angelegt werden, damit mehrere Client-Anwendungen die Komponente unabhängig voneinander verwenden können und sich nicht die Standard-Instanz des Forms zu teilen brauchen.

Sinnvollerweise sollten Sie auch für eine Abbruchmöglichkeit sorgen, damit entweder der Benutzer der Client-Anwendung die Bearbeitung der Aufgabe vorzeitig abbrechen kann, oder damit deren Bearbeitung automatisch beendet werden kann, wenn die Client-Anwendung selbst beendet wird. Dazu sehen Sie eine Abbruch-Methode in der Verbindungsklasse vor, die in dieser eine Merk-Variable (mCancel) auf True setzt. Diese Merk-Variable ist dann während der Bearbeitung der Aufgabe regelmäßig abzufragen (nicht vergessen, eine DoEvents-Anweisung dort einzufügen, damit das Setzen der Mark-Variablen durchkommt). Ist sie gesetzt, wird die Bearbeitung abgebrochen.

Weiterhin muss ein weiterer Aufruf der Start-Methode während der Bearbeitung der Aufgabe verhindert werden. Auch hierzu wird eine Merk-Variable (mBusy) verwendet und gleich zu Beginn der Start-Methode gesetzt. Beim erneuten Aufruf der Start-Methode wird geprüft, ob mBusy gesetzt ist. Ist dies der Fall, wird erst gar nicht eine erneute Bearbeitung der Aufgabe initiiert, sondern der Aufruf gleich wieder beendet.

Nach Bearbeitung der Aufgabe können Sie ein Ereignis auslösen, das sowohl die Erledigung als das Ergebnis der Bearbeitung an die Client-Anwendung zurückmelden kann.

Das Code-Grundgerüst sieht folgendermaßen aus - zunächst die Verbindungsklasse (z.B. Async.cls):

Public Event Done(Ergebnis As Variant, Cancelled As Boolean)

Private mBusy As Boolean
Private mShowForm As Boolean
Private mForm As frmAsync
Private mCancel As Boolean

Private WithEvents eActionTimer As Timer

Private mData As Variant

Public Function Action(Data As Variant, Optional ShowForm As Boolean) _
 As Boolean

  If mBusy Then
    Action = True
    Exit Function
  End If
  mBusy = True
  mCancel = False
  mShowForm = ShowForm
  
  mData = Data

  Set mForm = New frmAsync
  Set eActionTimer = mForm.tmrAction
  eActionTimer.Enabled = True
End Function

Public Sub Cancel()
  mCancel = True
End Sub

Private Sub eActionTimer_Timer()
  Dim nErgebnis As Variant

  eActionTimer.Enabled = False
  Set eActionTimer = Nothing
  
  If mShowForm Then
    mForm.Show
    DoEvents

    '... Aufgabe bearbeiten, mit Anzeige
    DoEvents
    '... Aufgabe bearbeiten, mit Anzeige
    DoEvents
    '... Aufgabe bearbeiten, mit Anzeige
  Else
    '... Aufgabe bearbeiten, verdeckt
    DoEvents
    '... Aufgabe bearbeiten, verdeckt
    DoEvents
    '... Aufgabe bearbeiten, verdeckt
  End If
  
  RaiseEvent Done(nrgebnis)
  
  Unload mForm
  mBusy = False
End Sub

Private Sub Class_Terminate()
  If Not (eActionTimer Is Nothing) Then
    eActionTimer.Enabled = False
  End If
  Set eActionTimer = Nothing
  If Not (mForm Is Nothing) Then
    Unload mForm
  End If
End Sub

Und beispielsweise in der Client-Anwendung:

Private WithEvents eAction As Async

Private Sub cmdStart_Click()
  If eAction.Action(10000, CBool(chkShowForm.Value)) Then
    MsgBox "Aktion ist bereits aktiv!"
  Else
    cmdCancel.Enabled = True
  End If
End Sub

Private Sub cmdCancel_Click()
  eAction.Cancel
End Sub

Private Sub eAction_Done(Ergebnis As Variant, Cancelled As Boolean)
  cmdCancel.Enabled = False
  MsgBox "Ergebnis: " & Ergebnis
End Sub

Private Sub Form_Load()
  Set eAction = New Async
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode _
 As Integer)

  If Not (eAction Is Nothing) Then
    eAction.Cancel
  End If
End Sub

Beispiel- und Test-Projekt AsyncServer (callasync.zip - ca. 14 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer