Gründe für das Implementieren des ereignisbasierten asynchronen Musters

Mit dem ereignisbasierten asynchronen Muster kann das asynchrone Verhalten einer Klasse verfügbar gemacht werden. Mit der Einführung dieses Musters definiert .NET zwei Muster, um asynchrones Verhalten verfügbar zu machen: das asynchrone Muster basierend auf der Schnittstelle System.IAsyncResult und das ereignisbasierte Muster. In diesem Artikel wird beschrieben, in welchen Fällen die Muster implementiert werden sollten.

Weitere Informationen zur asynchronen Programmierung mit der IAsyncResult-Benutzeroberfläche finden Sie unter Asynchrones Programmiermodell (APM).

Allgemeine Prinzipien

Allgemein sollten Sie asynchrone Features, die das ereignisbasierte asynchrone Muster verwenden, nach Möglichkeit verfügbar machen. Es gibt jedoch einige Anforderungen, die das ereignisbasierte Muster nicht erfüllen kann. In diesen Fällen müssen Sie neben dem ereignisbasierten Muster möglicherweise auch das IAsyncResult-Muster implementieren.

Hinweis

Das IAsyncResult-Muster wird in den meisten Fällen zusammen mit dem ereignisbasierten Muster implementiert.

Richtlinien

In der folgenden Liste werden die Richtlinien beschrieben, in welchen Fällen das ereignisbasierte asynchrone Muster implementiert werden sollte:

  • Verwenden Sie das ereignisbasierte Muster als Standard-API, um asynchrones Verhalten für Ihre Klasse verfügbar zu machen.

  • Machen Sie das IAsyncResult-Muster nicht verfügbar, wenn Ihre Klasse in erster Linie in einer Clientanwendung wie Windows Forms eingesetzt wird.

  • Machen Sie das IAsyncResult-Muster nur verfügbar, wenn dies zur Erfüllung Ihrer Anforderungen notwendig ist. Das IAsyncResult-Muster muss beispielsweise verfügbar gemacht werden, um Kompatibilität mit einer vorhandenen API herzustellen.

  • Machen Sie das IAsyncResult-Muster nur in Verbindung mit dem ereignisbasierten Muster verfügbar.

  • Wenn Sie das IAsyncResult-Muster verfügbar machen, verwenden Sie hierfür eine erweiterte Option. Wenn Sie beispielsweise ein Proxyobjekt generieren, generieren Sie standardmäßig das ereignisbasierte Muster mit einer Option zum Generieren des IAsyncResult-Musters.

  • Ziehen Sie als Grundlage für die Implementierung Ihres ereignisbasierten Musters die Implementierung Ihres IAsyncResult-Musters heran.

  • Machen Sie das ereignisbasierte Muster und das IAsyncResult-Muster nicht für die gleiche Klasse verfügbar. Machen Sie das ereignisbasierte Muster für übergeordnete Klassen und das IAsyncResult-Muster Klassen für untergeordnete Klassen verfügbar. Vergleichen Sie z.B. das ereignisbasierte Muster für die WebClient-Komponente mit dem IAsyncResult-Muster für die HttpRequest-Klasse.

    • Machen Sie das ereignisbasierte Muster und das IAsyncResult-Muster für die gleiche Klasse verfügbar, wenn dies zur Bereitstellung von Kompatibilität erforderlich ist. Wenn Sie z.B. bereits eine API freigegeben haben, die das IAsyncResult-Muster verwendet, müssten Sie das IAsyncResult-Muster zum Bereitstellen von Abwärtskompatibilität beibehalten.

    • Machen Sie das ereignisbasierte Muster und das IAsyncResult-Muster für die gleiche Klasse verfügbar, wenn die resultierende Objektmodellkomplexität den Vorteil einer Trennung der Implementierungen überwiegt. Es ist besser, beide Muster für eine einzelne Klasse verfügbar zu machen, als auf die Bereitstellung des ereignisbasierten Musters zu verzichten.

    • Wenn Sie sowohl das ereignisbasierte Muster als auch das IAsyncResult-Muster für eine einzelne Klasse verfügbar machen müssen, legen Sie EditorBrowsableAttribute auf Advanced fest, um die Implementierung des IAsyncResult-Musters als erweitertes Feature zu kennzeichnen. Dies ist ein Hinweis für Entwurfsumgebungen wie Visual Studio IntelliSense, nicht die IAsyncResult-Eigenschaften und -Methoden anzuzeigen. Diese Eigenschaften und Methoden sind weiterhin im vollen Umfang nutzbar, aber Entwickler, die mit IntelliSense arbeiten, haben einen umfassenderen Überblick über die API.

Kriterien für das Verfügbarmachen des IAsyncResult-Musters zusätzlich zum ereignisbasierten Muster

Das ereignisbasierte asynchrone Muster bietet zwar zahlreiche Vorteile im Zusammenhang mit den zuvor erläuterten Szenarien, bringt jedoch auch einige Nachteile mit sich, die Sie berücksichtigen sollten, wenn Leistung an oberster Stelle für Sie steht.

Es gibt drei Szenarien, die weder das ereignisbasierte Muster noch das IAsyncResult-Muster bewältigen:

Diese Szenarien können mithilfe des ereignisbasierten Musters bewältigt werden, was jedoch umständlicher ist als die Verwendung des IAsyncResult-Musters.

Entwickler verwenden häufig das IAsyncResult-Muster für Dienste, die üblicherweise eine sehr hohe Leistung erfordern. Der Abruf des Beendigungsszenarios ist beispielsweise ein leistungsintensives Serververfahren.

Darüber hinaus ist das ereignisbasierte Muster weniger effizient als das IAsyncResult-Muster, da mehrere Objekte, insbesondere EventArgs, erstellt werden und es threadübergreifend synchronisiert wird.

Die folgende Liste enthält einige Empfehlungen, die Sie bei Verwendung des IAsyncResult-Musters berücksichtigen sollten:

  • Machen Sie das IAsyncResult-Muster nur verfügbar, wenn Sie insbesondere Unterstützung für WaitHandle- oder IAsyncResult-Objekte benötigen.

  • Machen Sie das IAsyncResult-Muster nur verfügbar, wenn Sie eine API basierend auf diesem IAsyncResult-Muster besitzen.

  • Wenn Sie über eine API basierend auf dem IAsyncResult-Muster verfügen, sollten Sie das ereignisbasierte Muster zudem im nächsten Release verfügbar machen.

  • Machen Sie das IAsyncResult-Muster nur verfügbar, wenn Sie über hohe Leistungsanforderungen verfügen, die gemäß Ihrer Feststellung nicht mit dem ereignisbasierten Muster, jedoch mit dem IAsyncResult-Muster erfüllt werden können.

Weitere Informationen