Implementieren der Geschäftsschichtserver in Visual Basic

Veröffentlicht: 15. Sep 2000 | Aktualisiert: 17. Jun 2004

Sie wissen bereits, wie Ihre Anwendung strukturiert sein wird. Wenn Sie einen statusbehafteten Entwurf gewählt haben, sind Sie sich der möglichen Nachteile bewusst. Die Implementierung Ihres Entwurfs ist vielleicht der letzte Faktor, der sich auf dessen Erfolg auswirkt. Alle diese Punkte haben Einfluss darauf, wie Sie Ihre Codeanweisungen schreiben und Ihr Projekt und Ihre Klassen ordnungsgemäß; konfigurieren.

Sie sollten auch auf den folgenden Hyperlink zugreifen, der nützliche Informationen zum MTS/COM+-Komponentendebugging enthält.

INFO: Visual Basic 6.0 Readme Part 12 – Transaction Server (MTS) Issues (Q170156) (in Englisch)

Auf dieser Seite

Legen Sie eine Benennungskonvention fest Legen Sie eine Benennungskonvention fest
Verwenden Sie keine gemeinsam genutzten globalen Variablen Verwenden Sie keine gemeinsam genutzten globalen Variablen
Vermeiden Sie es, "GetObjectContext" in "_Activate" aufzurufen, wenn Sie den Kontext nicht ständig benötigen Vermeiden Sie es, "GetObjectContext" in "_Activate" aufzurufen, wenn Sie den Kontext nicht ständig benötigen
Verwenden Sie "ObjectControl_Activate" und "ObjectControl_Deactivate" anstelle von "Class_Initialize" und "Class_Terminate" Verwenden Sie "ObjectControl_Activate" und "ObjectControl_Deactivate" anstelle von "Class_Initialize" und "Class_Terminate"
Vermeiden Sie kostspielige oder fehleranfällige Aktivitäten in "Sub Main()" Vermeiden Sie kostspielige oder fehleranfällige Aktivitäten in "Sub Main()"
Rufen Sie Ressourcen spät ab, und geben Sie diese früh frei Rufen Sie Ressourcen spät ab, und geben Sie diese früh frei
Verwenden Sie beim Programmieren Thread-sichere Operationen Verwenden Sie beim Programmieren Thread-sichere Operationen
Verwenden Sie eine frühe Bindung, wann immer möglich Verwenden Sie eine frühe Bindung, wann immer möglich
Deklarieren Sie Parameter nach Möglichkeit als "ByVal" Deklarieren Sie Parameter nach Möglichkeit als "ByVal"
Verwenden Sie nicht die Funktionen "GetSetting" und "SaveSetting" in Ihren Projekten Verwenden Sie nicht die Funktionen "GetSetting" und "SaveSetting" in Ihren Projekten
Wählen Sie in Ihrem Projekt das Threadingmodell "Apartment Threaded" Wählen Sie in Ihrem Projekt das Threadingmodell "Apartment Threaded"
Aktivieren Sie das Kontrollkästchen "Unbeaufsichtigte Ausführung" für Ihr Projekt Aktivieren Sie das Kontrollkästchen "Unbeaufsichtigte Ausführung" für Ihr Projekt
Aktivieren Sie das Kontrollkästchen "In Speicher erhalten" für Ihr Projekt Aktivieren Sie das Kontrollkästchen "In Speicher erhalten" für Ihr Projekt
Verwenden Sie keine Klassen mit globaler Mehrfachverwendung Verwenden Sie keine Klassen mit globaler Mehrfachverwendung
Deklarieren Sie Variablen nicht "As New…" Deklarieren Sie Variablen nicht "As New…"
Erstellen Sie Objekte in demselben Projekt nicht mit dem "New"-Schlüsselwort Erstellen Sie Objekte in demselben Projekt nicht mit dem "New"-Schlüsselwort
Erstellen Sie Ihre Objekte mit dem richtigen Operator Erstellen Sie Ihre Objekte mit dem richtigen Operator
Verwenden Sie beim Kompilieren die Option "Debug-Informationen für symbolischen Debugger generieren" Verwenden Sie beim Kompilieren die Option "Debug-Informationen für symbolischen Debugger generieren"

Legen Sie eine Benennungskonvention fest

Beim Schreiben der Codeanweisungen für Ihre Komponenten sollten Sie bestimmte Regeln für die Namen von Präfixen und Elementen befolgen. Auf diese Weise sind die Codeanweisungen leichter verwaltbar, Fehler können einfacher behandelt werden, und bei der Codeerstellung treten weniger Fehler auf.

Weitere Informationen

Sie können Benennungskonventionen für Folgendes festlegen:

  • Variablen

  • Klassen

  • Funktionen und Parameter

  • Projekte

  • Datenbankobjekte (Tabellen, gespeicherte Prozeduren usw.)

  • Gemeinsam genutzte Eigenschaften

Vorgehensweise

Es gibt viele Informationen zu diesem Thema. Berücksichtigen Sie jedoch stets die folgenden Richtlinien:

  • Verwenden Sie keine Abkürzungen (z.B. fopen anstelle von OpenFile).

  • Verwenden Sie entweder ein Nomen-Verb-Schema oder ein Verb-Nomen-Schema (FileOpen oder OpenFile).

  • Verwenden Sie Groß;- und Kleinschreibung (DeleteExpiredSubscribers anstelle von deleteexpiredSubscribers).

  • Verwenden Sie Unterstriche konsistent (sp_add_user anstelle von sp_removeuser).

  • Verwenden Sie Plural und Singular konsistent (SELECT * FROM Authors INNER JOIN Book).

Referenzmaterial

INFO: Microsoft Consulting Services Naming Conventions for Visual Basic (Q110264) (in Englisch)

 

Verwenden Sie keine gemeinsam genutzten globalen Variablen

Visual Basic 6.0 speichert eine separate Instanz einer globalen Variablen auf Threadbasis. D.h., wenn Sie eine globale Variable verwenden, in die ein MTS-Objekt schreibt, sehen andere MTS-Objekte nur dann denselben Wert, wenn sie auf demselben Thread ausgeführt werden. Die Wahrscheinlichkeit, dass dies in einem statusbehafteten oder statusfreien Programmiermodell auf regelmäß;iger Basis geschieht, ist jedoch relativ gering. Fazit: Verlassen Sie sich nicht darauf, dass alle Objekte in globalen Variablen dieselben Daten sehen.

Vorgehensweise

Stellen Sie sicher, dass Ihre Anwendung keine globale Variable (z.B. für das Speichern eines Zählers) verwendet, die von mehreren Aktivitäten gemeinsam genutzt wird. Platzieren Sie einen vorübergehenden globalen Status im SPM, wenn die SPM-Qualifikationen erfüllt werden. Andernfalls platzieren Sie den Status in einer Datenbank.

Referenzmaterial

The Shared Property Manager (in Englisch)
A Thread to Visual Basic von Dan Appleman (in Englisch)

 

Vermeiden Sie es, "GetObjectContext" in "_Activate" aufzurufen, wenn Sie den Kontext nicht ständig benötigen

Details

Die Lebensdauer des Objektkontexts erstreckt sich zwar über den Zeitraum zwischen den Methoden Activate und Deactivate der ObjectControl-Schnittstelle, i.d.R. empfiehlt es sich jedoch, bei Bedarf einen Verweis auf den Kontext abzurufen.

Weitere Informationen

Ein typischer Funktionsaufruf verwendet ObjectContext nur ein- oder zweimal, um die Entscheidung für die aktuelle Transaktion festzulegen oder einige Attribute zu verwenden. In diesem Fall werden kaum zusätzliche Computeranweisungen ausgeführt, wenn Sie GetObjectContext jedes Mal verwenden, und die Codeanweisungen bleiben übersichtlicher und einfacher zu verwalten.

Wenn Sie den Objektkontext jedoch wiederholt verwenden (wenn Sie z.B. das ASP-Objekt Response durch die ObjectContext.Item-Auflistung verwenden), sollten Sie einen Verweis innerhalb der Funktion abrufen und diesen auf Nothing setzen, wenn Sie den Task abgeschlossen haben. Sie können auch eine WITH-Anweisung verwenden, um die wiederholte Verwendung derselben Variable zu vermeiden. Auf diese Weise erstellen Sie leichter lesbare und verwaltbare Codeanweisungen und optimieren die Ausführungszeiten.

 

Verwenden Sie "ObjectControl_Activate" und "ObjectControl_Deactivate" anstelle von "Class_Initialize" und "Class_Terminate"

Das Class_Initialize-Ereignis tritt ein, bevor das Objekt der COM+-Aktivitätssteuerung unterstellt wird. Dies bewirkt, dass Ihr Projekt weniger vorhersehbar und schwieriger zu debuggen ist. So ist beispielsweise der Objektkontext nicht verfügbar, Datenbankverbindungen sind nicht in Transaktionen aufgeführt, und VB kann beim Debuggen dieser Methoden abstürzen.

Weitere Informationen

Wenn ein Objekt für die Ausführung in COM+ erstellt wird, verfügt es über eine interne Struktur, die als Kontext bezeichnet wird und bestimmte Informationen verkapselt, z.B. Transaktionseintragung, Threadingmodell usw. Wenn das Class_Initialize-Ereignis ausgeführt wird, wurde der Kontext noch nicht dem Objekt zugeordnet. Dies hat folgende Konsequenzen:

  • Datenbankverbindungen werden nicht in aktuelle Transaktionen eingetragen.

  • Die erstellten untergeordneten Objekte nutzen die Kontextinformationen nicht gemeinsam.

Anmerkung Es müssen sehr spezifische Gründe für das Ausführen der o.g. Aktionen vorliegen, da die Konstruktor- oder Destruktormethoden in einem rein statusfreien Objektentwurf nicht erforderlich sein sollten.

Vermeiden Sie das Ausführen der folgenden Operationen in ObjectControl_Activate und ObjectControl_Deactivate:

  • Aufrufen von SetComplete/SetAbort

  • Aufrufen von anderen Objekten

  • Ausführen von fehleranfälligen Operationen (Zugreifen auf Datenbanken), die einen Fehler in der aktuellen Transaktion auslösen können

Vorgehensweise

Fügen Sie Implements ObjectControl an oberster Stelle in Ihrem Klassenmodul hinzu. Verschieben Sie die Codeanweisungen aus Class_Initialize in ObjectControl_Activate sowie die gesamten Codeanweisungen aus Class_Terminate in ObjectControl_Deactivate (sofern vorhanden). Stellen Sie dann sicher, dass Sie keine Aktionen ausführen, die das ordnungsgemäß;e Funktionieren Ihres Objekts beeinträchtigen.

Innerhalb dieser Richtlinien sollten diese beiden Ereignisse anstelle der Visual Basic-Ereignisse Initialize und Terminate für Komponenten verwendet werden, die in COM+ ausgeführt werden.

 

Vermeiden Sie kostspielige oder fehleranfällige Aktivitäten in "Sub Main()"

Sobald Ihre Komponente in COM+ gestartet wurde, wird bei der ersten Objektanforderung die Sub Main()-Routine aufgerufen. Wenn Sie jedoch langwierige Codeanweisungen verwenden (z.B. Datenzugriff, Laden von groß;en Dateien, Analysieren und Zeichenfolgenbearbeitung), wird i.d.R. die Fehlermeldung ID 10010 mit folgendem Text in der Ereignisanzeige angezeigt: "The server {hier Ihre CLSID} did not register itself with DCOM within the required timeout", selbst wenn die Codeanweisung fehlerfrei ist. Wenn dies noch kein hinreichender Grund ist, diese Vorgehensweise zu vermeiden, sollten Sie sich eine andere Einschränkung vor Augen führen: Ihre Clients können die Komponenten nicht erstellen und erhalten auch keine nützlichen Fehlerinformationen.

Vorgehensweise

Wenn Sie sich darauf verlassen, dass ein vorübergehender oder zwischengespeicherter Status für Ihre Komponente initialisiert wird, sollten Sie diesen nach Möglichkeit bei Bedarf initialisieren. Sie sollten Ihre Komponente keiner Operation aussetzen, die fehlschlagen könnte, bevor die Komponente lange genug existiert hat, um Sie darüber informieren zu können, wieso sie beendet wurde. Wenn Sie die Sub Main ()-Routine nicht verwenden, ist Ihre Komponente leichter zu verwalten und zu debuggen, und auch Fehler sind leichter zu behandeln.

Weitere Informationen

Dieses Fehlerereignis tritt ein, da DCOM zwar eine bestimmte Klasse angefordert und den Server gestartet hat, der Server seine Initialisierungsphase jedoch nicht innerhalb des vorgegebenen Timeouts abschließ;en konnte (d.h., die ClassFactory wurde nicht registriert).

 

Rufen Sie Ressourcen spät ab, und geben Sie diese früh frei

Vermeiden Sie es, Ressourcen (offene Dateien, Datenbankverbindungen, Datenbanksperrungen, Arbeitsspeicher usw.) länger besetzt zu halten als unbedingt erforderlich. So sollten Sie z.B. eine Verbindung zu einer Datenbank erst kurz vor deren Verwendung herstellen (d.h. unmittelbar vor dem Ausführen eines Befehls oder dem Aktualisieren von Parametern). Auß;erdem sollten Sie die Ressourcen früh freigeben, d.h. Ihre Verbindungen schließ;en, und Ressourcen, die gemeinsam genutzt werden können, freigeben, sobald Sie diese nicht mehr benötigen. Auf diese Weise erhöhen Sie die Skalierbarkeit Ihrer Anwendung aufgrund der effizienteren Zeitspannen für die Ressourcenzuordnung.

So legen Sie z.B. beim Ausführen einer gespeicherten Prozedur so viele Optionen für Ihre ADO-Objekte wie möglich vor dem Herstellen der Datenbankverbindung fest (Verbindungsoptionen, Befehlsparameter usw.). Sobald Sie die Verbindung hergestellt haben, führen Sie nur die erforderlichen Operationen durch (Ausführen einer gespeicherten Prozedur, Abrufen eines Resultsets und Trennen der Verbindung zum Recordset) und schließ;en dann die Verbindung so bald wie möglich, damit Sie mit dem Ausführen fortfahren können, ohne eine unnötige Verbindung aufrechtzuerhalten.

Weitere Informationen

Wenn ein Serverobjekt eine Ressource länger als erforderlich belegt, ist diese Ressource für keinen anderen Client verfügbar. Ressourcen wie Datenbankverbindungen, Threads, Arbeitsspeicher, Sperrungen usw. sind nur begrenzt verfügbar und sollten daher sparsam verwendet werden. Im Client/Server-Bereich können Sie sich eine solche Vorgehensweise für eine gewisse Zeit erlauben, bevor sich die Auswirkungen auf die Benutzer bemerkbar machen. In verteilten n-tier-Anwendungen mittleren Volumens bekommen Tausende von Benutzern die Auswirkungen zu spüren. Berücksichtigen Sie bei der Planung und Entwicklung von Anfang an eine effiziente Ressourcenverwendung.

Referenzmaterial

Microsoft Systems Journal: Q&A ActiveX/COM von Don Box (in Englisch)
Holding State in Objects (in Englisch)

 

Verwenden Sie beim Programmieren Thread-sichere Operationen

Visual Basic ist zwar eine ausgezeichnete Sprache für das Entwickeln von Serverkomponenten, doch bestimmte Funktionen innerhalb dieses Produkts sind nicht für eine ressourcenintensive "GUI-freie" oder serverseitige Verwendung bestimmt. Das Implementieren einer serverseitigen Lösung mit diesen zweckgebundenen Features zieht eine Instabilität Ihrer Serverprozesse nach sich. Die folgenden Szenarios sollten nicht in Verbindung mit serverseitigen Geschäftsobjekten ausgeführt werden:

  • Aufrufen von DoEvents

  • Auslösen eines Ereignisses, das von einem Objekt in einem anderen Thread oder in einem anderen Prozess verarbeitet wird

  • Anzeigen eines Formulars

  • Aufrufen einer Bibliothek oder Komponente, die nicht für die Serververwendung entworfen und sorgfältig getestet wurde

Referenzmaterial

Entwerfen von Thread-sicheren DLLs

 

Verwenden Sie eine frühe Bindung, wann immer möglich

Frühe Bindungen (d.h. das Deklarieren von Objektvariablen als Bestandteil der spezifischen Klasse oder Schnittstelle, anstatt als Objekt) können eine erhebliche Steigerung der Anwendungsleistung bewirken.

Weitere Informationen

Eine frühe Bindung liegt vor, wenn Sie ein Objekt über eine Variable verwenden, die als zum richtigen Typ gehörig deklariert ist, z.B.:

Dim oHouse As CHouse

-Oder-

Dim oHouse As Iasset

Sie verwenden späte Bindung, wenn Ihre Variable wie folgt deklariert ist:

Dim oHouse As Object

-Oder-

Dim oHouse As Variant. 

Beachten Sie, dass dies nichts mit dem Operator zu tun hat, der für das Instantiieren des Objekts (über CreateInstance, CreateObject oder New) verwendet wird. In jedem Fall erfordert eine frühe Bindung, dass in Ihrem VB-Projekt die richtigen Verweise festgelegt sind.

Spät gebundene Aufrufe werden über eine COM-Schnittstelle mit der Bezeichnung IDispatch ausgeführt, die für das Ausführen einer bestimmten Methode zwei Aufrufe benötigt. Der erste Aufruf, GetIDsOfNames, wird verwendet, um eine ID für eine bestimmte Methode abzurufen, und der zweite Aufruf, Invoke, wird verwendet, um die Parameter zu senden und den Aufruf auszuführen.

Bei produktionsbereiten Implementierungen werden nur im Ausnahmefall spät gebundene Objekte verteilt. Einige Entwicklungsumgebungen profitieren im Frühstadium von Prototyp- und Verwendbarkeitstests von der flexiblen Kopplung bei einer späten Bindung. Je größ;er Projekte jedoch werden und je mehr Entwickler online gehen, desto deutlicher zeigt sich, dass eine frühe Bindung vor inkompatiblen Schnittstellen und verwirrenden Codestrukturen schützt. Weitere Vorteile der frühen Bindung sind die Vorcompilerüberprüfung sowie die Nutzung des IntelliSense-Features in VB.

Vorgehensweise

Fügen Sie der Bibliothek Verweise auf die Schnittstellen oder Objekte hinzu, die Sie verwenden möchten:

Dim As [Hier Ihr(e) Klassenname/Schnittstelle].

Referenzmaterial

Deklarieren von Objektvariablen
INFO: Using Early Binding and Late Binding in Automation (Q245115) (in Englisch)

 

Deklarieren Sie Parameter nach Möglichkeit als "ByVal"

Visual Basic definiert Parameter standardmäß;ig nach Verweis (ByRef). Für das Übergeben dieser Parameter nach Wert (so dass der Parameter nicht unter unnötiger Verwendung des Netzwerks zurück übertragen wird) deklarieren Sie die Parameter unter Verwendung des Schlüsselworts ByVal. Alle Parameter, die nicht das Schlüsselwort ByVal aufweisen, werden von Visual Basic standardmäß;ig auf ByRef gesetzt.

Weitere Informationen

Das Übergeben von Argumenten an eine Funktion kann nach Wert (ByVal) oder nach Verweis (ByRef) erfolgen. Bei Remoteaufrufen muss ein ByRef-Argument an den Server gesendet und dann an den Client zurückgesendet werden. Dies zieht zusätzlichen Netzwerkverkehr nach sich. Wenn der Client kein Zurücksenden der Daten erfordert, stimmt ein ByVal-Parameter zudem stärker mit der Schnittstellensemantik überein.

Weitere Informationen zu Einschränkungen bei der Verwendung dieser Dienste für Funktionen mit ByRef-Parametern finden Sie in den Abschnitten "Verwenden von Queued Components" und "Verwenden von COM+-Ereignissen".

Vorgehensweise

Fügen Sie für jeden Funktionsparameter, für den keine Kopie an den Client zurückgesendet werden muss, das Schlüsselwort ByVal hinzu.

Referenzmaterial

ByVal
INFO: Only Write-Only Interfaces Can be Marked as Queued in COM+ (Q246625) (in Englisch)

 

Verwenden Sie nicht die Funktionen "GetSetting" und "SaveSetting" in Ihren Projekten

VB stellt diese Funktionen als einfache und direkte Möglichkeit zum Lesen der Registrierung bereit. Sie sind jedoch für Desktopanwendungen bestimmt und lesen einen Registrierungsabschnitt, der für die eindeutige Benutzer-ID der Person spezifisch ist, die die Anwendung benutzt (HKEY_CURRENT_USER).

Weitere Informationen

Die von VB bereitgestellten Funktionen für den Zugriff auf die Registrierung sind nicht für die Verwendung in einer Serverumgebung bestimmt. Sie können andere Vorgehensweisen für den Zugriff auf die Registrierung in Betracht ziehen oder standardmäß;ig Dateien laden. In Serverumgebungen wird der benutzerspezifische Abschnitt der Registrierung für die spezifische MTS-Paket-ID nicht geladen. Stattdessen wird der Standardschlüssel des Benutzers verwendet. Dabei kommt es jedoch u.U. vor, dass Anwendungen, die unter Interaktiver Benutzer fehlerfrei ausgeführt werden, abstürzen, wenn niemand beim Server angemeldet ist.

Vorgehensweise

Es gibt viele Objekte, die ebenfalls das Lesen und Schreiben in der Registrierung ermöglichen, jedoch stabiler sind und auf die gesamte Registrierung zugreifen können. Diese werden sowohl von anderen Herstellern als auch in den MSDN-Beispielen bereitgestellt.

Auß;erdem sollten Sie in Erwägung ziehen, anstelle der Registrierung Dateien zu verwenden. Dateien auf einem NTFS-Laufwerk können wesentlich einfacher gesichert, verwaltet, repliziert und programmiert werden als Registrierungseinstellungen.

 

Wählen Sie in Ihrem Projekt das Threadingmodell "Apartment Threaded"

In Visual Basic 6.0 können Ihre DLLs entweder Single Threaded oder Apartment Threaded sein. Wählen Sie das Threadingmodell Apartment Threaded.

Weitere Informationen

Visual Basic kann Apartment Threaded-Komponenten oder Single Threaded-Komponenten erstellen. Apartment Threaded ist das Modell, das für das parallele Arbeiten unter MTS erforderlich ist. Wenn das Modell Single Threaded ausgewählt ist, werden alle Methodenaufrufe für die Instanzen der DLL-Objekte serialisiert. Unter Verwendung von Single Threaded-Komponenten erstellte Anwendungen sind jedoch nur begrenzt skalierbar, da alle Methodenaufrufe in einzeiliger Formation erfolgen, selbst wenn sie in verschiedenen Objektinstanzen ausgeführt werden.

Vorgehensweise

Klicken Sie auf Projekt, wählen Sie den Befehl Eigenschaften, und wählen Sie auf der Registerkarte Allgemein im Feld Threading-Modell die Option Apartment Threaded.

Referenzmaterial

COM & Threading
Neutral Apartments (in Englisch)
FIX: VB 6 DLL Settings Cause Access Violation During MTS Shutdown (Q214755) (in Englisch)
Threading nach dem Apartment-Modell in Visual Basic

 

Aktivieren Sie das Kontrollkästchen "Unbeaufsichtigte Ausführung" für Ihr Projekt

In Visual Basic 5.0 und Visual Basic 6.0 können Sie über ein Kontrollkästchen in den Projekteigenschaften die Option Unbeaufsichtigte Ausführung wählen. Stellen Sie vor dem Kompilieren sicher, dass dieses Kontrollkästchen aktiviert ist.

Weitere Informationen

Dieses Attribut legt fest, dass Ihre Komponente ohne Benutzerinteraktion ausgeführt wird. D.h., alle Meldungsfelder, die über MsgBox aufgerufen werden, werden als NT-Ereignisse protokolliert. (Im Folgenden erhalten Sie Informationen zu einem besseren Verfahren für das Protokollieren von Ereignissen.)

In Visual Basic 6.0 wird, anders als in VB 5.0, das Threadingmodell Ihrer Komponente nicht geändert.

Vorgehensweise

Klicken Sie auf Projekt, wählen Sie den Befehl Eigenschaften, und aktivieren Sie auf der Registerkarte Allgemein das Kontrollkästchen Unbeaufsichtigte Ausführung.

 

Aktivieren Sie das Kontrollkästchen "In Speicher erhalten" für Ihr Projekt

In Visual Basic 6.0 können Sie über ein Kontrollkästchen in den Projekteigenschaften die Option In Speicher erhalten wählen. Stellen Sie vor dem Kompilieren sicher, dass dieses Kontrollkästchen aktiviert ist.

Weitere Informationen

Dieses Attribut legt fest, wie sich die Lebensdauer Ihrer Komponente auf das Laden/Entladen der erforderlichen DLLs auswirkt. Wenn dieses Kontrollkästchen nicht aktiviert ist, können DLLs in einer unerwarteten Reihenfolge freigegeben werden, die dazu führen kann, dass Ihre Anwendung beim Herunterfahren abstürzt, normale Bereinigungsverfahren unterbrochen werden und einige mehrdeutige Fehler sowie nichtdefinierte Verhalten auftreten.

Vorgehensweise

Klicken Sie auf Projekt, wählen Sie den Befehl Eigenschaften, und aktivieren Sie auf der Registerkarte Allgemein die Kontrollkästchen Unbeaufsichtigte Ausführung und In Speicher erhalten.

 

Verwenden Sie keine Klassen mit globaler Mehrfachverwendung

Klassen mit globaler Mehrfachverwendung sind für die clientseitige Entwicklung äuß;erst nützlich. Für serverseitige DLLs, die i.d.R. ein statusfreies Modell verwenden und Kenntnisse über die Lebensdauer der Serverobjekte erfordern, sollte diese Einstellung jedoch nicht verwendet werden.

Weitere Informationen

Die Einstellung Globale Mehrfachverwendung ermöglicht Ihren Clients die Verfügbarkeit einer bestimmten Klasseninstanz sowie die Verfügbarkeit der Methoden dieser Klasse im globalen Namespace. Diese Einstellung ist ein Programmierungsfeature, das das Schreiben von clientseitigen Codeanweisungen vereinfacht, dafür jedoch VB die Kontrolle über die Lebensdauer des Objekts auf dem Server überlässt. Vermeiden Sie diese Einstellung daher in einer verteilten Umgebung.

Vorgehensweise

Sie sollten die Klasse auf Mehrfachverwendung anstatt auf Globale Mehrfachverwendung setzen und sie dann nach Bedarf auf dem Client erstellen und löschen.

Referenzmaterial

BUG: IDE Crash with Compiled GlobalMultiUse (Q187983) (in Englisch)
Instancing-Eigenschaft

 

Deklarieren Sie Variablen nicht "As New…"

Wenn Sie eine Variable eines Objekttyps deklarieren, können Sie das Schlüsselwort As New… verwenden. Dies spart Ihnen die Mühe, die Codezeile schreiben zu müssen, die das Objekt tatsächlich erstellt. Es verlangsamt allerdings auch alle Verweise auf das Objekt und kann eine unerwartete Objektlebensdauer bewirken. Auß;erdem kann in Verbindung mit privaten Klassen unerwartetes Threadverhalten auftreten.

Weitere Informationen

Wenn Sie eine Variable mit dem Schlüsselwort As New… deklarieren, weisen Sie Visual Basic an, bei Bedarf eine Objektinstanz zu erstellen. Visual Basic führt bei der Kompilierung Ihres Quellcodes zusätzliche Überprüfungen durch, um festzustellen, ob das Objekt auf Nothing gesetzt ist. Wenn das Objekt nicht gelöscht wurde, erstellt Visual Basic bei jeder Verwendung der Variablen ein neues Objekt.

Einige Ergebnisse hinsichtlich der Objektlebensdauer können auch recht überraschend sein.

Dim o As New Project1.CSample 
o.Foo 
Set o = Nothing 
MsgBox o Is Nothing 'Fehler! o ist nie gleich Nothing 

Durch dieses Verhalten ist Ihr Code schwerer zu verwalten, und es werden Fehler ausgelöst, die schwer zu erkennen sind. Die Verwendung des Schlüsselworts As New hat auch Auswirkungen auf die Erstellung des Objekts (weitere Informationen dazu erhalten Sie über den folgenden Hyperlink).

Vorgehensweise

Stellen Sie sicher, dass Sie Ihre Objekte in separaten Schritten deklarieren und erstellen.

Referenzmaterial

INFO: Use of New Keyword In MTS Environment (Q202535) (in Englisch)

 

Erstellen Sie Objekte in demselben Projekt nicht mit dem "New"-Schlüsselwort

Wenn Sie das Schlüsselwort New für das Erstellen eines Objekts in demselben Projekt verwenden, umgehen Sie COM+-Objekterstellungsmechanismen. Ihre Objekte weisen daher in Transaktionen nicht das erwartete Verhalten hinsichtlich der Sicherheit oder des Threadings auf.

In COM+ übergeben sowohl das Schlüsselwort New als auch die CreateObject-Funktion den Kontext (Transaktion, Sicherheit usw.) an das untergeordnete Objekt, falls sich das erstellte Objekt in einem anderen Projekt befindet. Wenn sowohl die erstellende (übergeordnete) Klasse als auch die untergeordnete Klasse in demselben Visual Basic-Projekt enthalten sind, müssen Sie CreateObject verwenden.

Vorgehensweise

Über den folgenden Hyperlink erhalten Sie Informationen zu Richtlinien für die Objekterstellung.

Referenzmaterial

INFO: Use of New Keyword In MTS Environment (Q202535) (in Englisch)
"Funktionsweise der Objekterstellung in Visual Basic-Komponenten"

 

Erstellen Sie Ihre Objekte mit dem richtigen Operator

Die CreateObject-Funktion und das Schlüsselwort New verhalten sich unterschiedlich, je nach Szenario. Objekte, die in COM+ ausgeführt werden, können entweder unter Verwendung der CreateObject-Funktion oder über das Schlüsselwort New erstellt werden. Beide Vorgehensweisen stellen sicher, dass das untergeordnete Element den Kontext des übergeordneten Elements erbt und das Objekt für das richtige Apartment erstellt wird. Sie müssen ObjectContext.CreateInstance in COM+ nicht verwenden.

Die Verwendung von CreateObject ermöglicht es Ihnen, die ProgID und den Speicherort (Computer) für das Projekt anzugeben, während Sie bei Verwendung des Schlüsselworts New über die lokalen Registrierungsinformationen eine Instanz der spezifischen Klasse erstellen können, auf die Ihr Projekt verweist.

Ein häufiger Fehler besteht darin, dass der New-Operator für das Erstellen von Objekten in derselben DLL verwendet wird. Der New-Operator in Visual Basic umgeht standardmäß;ige COM-Objekterstellungsmechanismen und verhindert daher die Kontextübertragung auf das untergeordnete Objekt.

Vorgehensweise

Verwenden von New:

  • Für das Erstellen von Dienstprogrammobjekten oder Objekten wie ADO, MSXML, CDO, MSMQ.

  • Für das Erstellen von benutzerdefinierten Objekten in einem anderen Projekt oder einer anderen DLL.

Verwenden von CreateObject:

  • Für das Erstellen von benutzerdefinierten Objekten in demselben Projekt oder derselben DLL.

  • Für das Erstellen von Objekten über eine(n) laufzeitspezifizierte(n) ProgID und/oder Computer.

Die folgenden Codebeispiele veranschaulichen die richtige Verwendung der Erstellungsoperatoren:

Szenario 1: Erstellen von (registrierten oder nichtregistrierten) Objekten in COM+:

Set oXMLDom = CreateObject("Microsoft.XMLDOM") 
Set oTransfer = New OtherProject.CTransfer 
Set oDBConnection = New ADODB.Connection 

Szenario 2: Erstellen eines Objekts in derselben Visual Basic-DLL (d.h. in COM+):

Set oISPSubs = CreateObject("MyProject.CSubscription") 

Referenzmaterial

INFO: Use of New Keyword In MTS Environment (Q202535) (in Englisch)
Funktionsweise der Objekterstellung in Visual Basic-Komponenten

 

Verwenden Sie beim Kompilieren die Option "Debug-Informationen für symbolischen Debugger generieren"

Dieser Abschnitt enthält wichtige Informationen zur Fehlerbehandlung bei einem Absturz der Anwendung. So können Sie z.B. sehen, in welcher Funktion das Problem aufgetreten ist, den Inhalt Ihrer Variablen anzeigen und auf weitere wichtige Informationen zugreifen.

Vorgehensweise

Stellen Sie beim Kompilieren Ihrer DLL sicher, dass das Kontrollkästchen Debug-Informationen für symbolischen Debugger generieren auf der Registerkarte Kompilieren (Dialogfeld Optionen) aktiviert ist. Auf diese Weise wird an der Position, an der Sie Ihre DLL kompiliert haben, eine PDB-Datei erstellt. Bei der Bereitstellung der DLL sollten Sie sicherstellen, dass die PDB-Datei in demselben Verzeichnis gespeichert wird wie die DLL. Auß;erdem sollten Sie sich vergewissern, dass die PDB und die DLL einander entsprechen, denn beide Dateien müssen zusammen erstellt und weitergeben werden, um zusammen verwendet werden zu können.

Sie müssen sich keine Gedanken über den Laufzeitaufwand machen, da dieser Aspekt beim Erstellen von symbolischen Debuggerinformationen, die auß;erhalb der EXE- oder DLL-Datei gespeichert werden, keine Rolle spielt. Dies hat auch keine Auswirkungen auf Ihre Serverumgebung. Diese Dateien bleiben statisch, bis Ihre Anwendung ausgeführt wird, und werden verwendet, um den Fehlerkontext zu überprüfen.

Wenn Ihre Serveranwendung z.B. scheinbar willkürlich abstürzt, sollten Sie zunächst feststellen, wann und warum der Fehler auftritt. Wenn Sie zur Lösung des Problems einen einfachen Debugger verwenden und über die PDB-Dateien für Ihre Komponente verfügen, haben Sie u.U. alle Informationen, die Sie zur Isolierung des Problems benötigen (z.B. welche Funktionsaufrufe das Problem ausgelöst haben, die Funktionsparameter und den Status der DLL-Variablen).

Referenzmaterial

Compiler-Optionen für systemeigenen (native) Code