Einführung
Microsoft hat kürzlich eine neue Plattform zur Generierung integrierter Anwendungen auf den Markt gebracht – das Microsoft
.NET Framework. .NETTO
Das Framework ermöglicht Entwicklern die schnelle Generierung und Bereitstellung von Webdiensten und Anwendungen in jeder Programmiersprache. Microsoft Intermediate Language (MSIL) und Echtzeit
Der
(JIT)-Compiler ermöglicht dieses sprachunabhängige Framework.
C# ist eine einfache, neuartige, objektorientierte und typsichere Programmiersprache. Nutzung von .NET
Frameworks
und C# (zusätzlich zu Microsoft? Visual Basic? und Managed C++) können Benutzer
leistungsstark schreiben
Microsoft Windows? und Webanwendungen und -dienste. Dieser Artikel
bietet eine solche Lösung und konzentriert sich dabei eher auf .NET Framework und C# als auf die Programmiersprache
Wörter. Eine Einführung in die Sprache C# finden Sie in „C# Introduction and Overview (English)“.
Stellt eine Lösung für den skalierbaren Lastausgleich von Nachrichtenwarteschlangen mit hoher Verfügbarkeit (MSMQ) vor.
Lösungsarchitektur. Diese Lösung beinhaltet die Entwicklung eines Windows-Dienstes als intelligenten Nachrichtenrouter. Eine solche Lösung gab es bisher nur von Microsoft
Visual C++
Programmierer können dies erreichen, und das Aufkommen des .NET Frameworks hat diese Situation geändert. Sie können dies in der Lösung
unten sehen.
.NET Framework-Anwendung
Die hier vorgestellte Lösung ist ein Windows-Dienst, der mehrere Nachrichtenwarteschlangen verwaltet;
Jede Warteschlange wird von mehreren Threads verarbeitet (Empfangen und Verarbeiten von Nachrichten). Handler machtRouten Sie Nachrichten aus der Zielwarteschlangentabelle
mithilfe von Round-Robin-Techniken oder anwendungsspezifischen Werten (AppSpecific-Eigenschaften für Nachrichten) und verwenden Sie die Nachrichteneigenschaften, um Komponentenmethoden aufzurufen. (Der Beispielprozess fällt ebenfalls in diese Kategorie
Situation. ) Im letzteren Fall besteht die Anforderung der Komponente darin, dass sie die angegebene Schnittstelle IWeb
Message implementiert. Um Fehler zu verarbeiten, muss die Anwendung Nachrichten, die nicht verarbeitet werden können, an die Fehlerwarteschlange senden.
Die Messaging-Anwendung ist insofern ähnlich aufgebaut wie die vorherige Active Template Library (ATL)-Anwendung
. Um einen Windows-Dienst zu erstellen, müssen .NET Framework-Benutzer lediglich einen Slave erstellen
Von ServiceBase
(von der System.ServiceControl-Assembly) geerbte Klasse. Dies ist keine Überraschung, da das .NET
Framework objektorientiert ist.
Anwendungsstruktur
Die Hauptklasse in der Anwendung ist ServiceControl, die
von ServiceBase erbt. Daher muss es OnStart und OnStop implementieren -Methode und die optionalen Methoden OnPause undOnContinue. Tatsächlich wird die Klasse innerhalb der statischen Methode Main erstellt:
using System
public class ServiceControl: ServiceBase
// Erstellen Sie den Haupteinstiegspunkt für das Serviceobjekt
public static void Main()
{
ServiceBase.Run(new ServiceControl());
}
// Konstruiertes Objekt, das Dienstparameter definiert
{
CanPauseAndContinue = true;
ServiceName = "MSDNMessageService";
AutoLog = false;
}
protected override void OnStart(string[] args) {...}
protected override void OnPause() {...}
protected override void OnContinue() {...}
}
Die ServiceControl-Klasse erstellt eine Reihe von CWorker-Objekten, d. h. für jede
erstellter Verarbeitungsthread führt die eigentliche Servicearbeit aus.
Der Hauptzweck der Verwendung der Klassen CWorker und CWorkerThread besteht darin, die Dienststeuerelemente Start,
Stop, Pause und Continue zu bestätigen
Befehl. Da diese Prozesse nicht blockierend sein dürfen, werden Befehlsoperationen
CWorkerThread ist eine abstrakte Klasse, definiert durch CWorkerThreadAppSpecific,
CWorkerThreadRoundRobin und CWorkerThreadAssembly erben. Diese Kategorien sind es nicht
Unterschied liegt in der Art und Weise, wie der Pfad der Empfangswarteschlange bestimmt wird), und die letzte Klasse verwendet Nachrichtenattribute zum Aufrufen
Verwenden Sie die Komponentenmethode.
Die Fehlerbehandlung innerhalb des .NET Frameworks basiert auf der Basisklasse Exception. Wenn das System
Fehler auslöst oder erkennt, müssen diese ihren Ursprung haben
In Exception exportierte Klassen. Die Klasse CWorker
Ob der Dienst weiterhin ausgeführt werden soll), um die Basisklasse zu erweitern.
Schließlich enthält die Anwendung zwei Strukturen. Diese Werttypen definieren
Laufzeitparameter für Arbeitsprozesse oder Threads, um CWorker und zu vereinfachen
Die Struktur des CWorkerThread-Objekts. Durch die Verwendung einer Werttyp-
-Struktur (anstelle einer Referenztypklasse) wird sichergestellt, dass diese Laufzeitparameter Werte beibehalten (anstelle von
-Referenzen).
IWebMessage-Schnittstelle
Eine der Implementierungen von CWorkerThread ist eine Klasse, die Komponentenmethoden aufruft. Diese Klasse namens
CWorkerThreadAssembly verwendet
Die IWebMessage-Schnittstelle definiert die Vereinbarung zwischen Diensten und Komponenten.
-Sprache definiert werden, ohne dass IDL-Dateien erstellt und kompiliert werden müssen. C#
Das
der IWebMessage-Schnittstelle ist wie folgt definiert:
öffentliche Schnittstelle IWebMessage
{
WebMessageReturn Process(string sMessageLabel, string sMessage
Body, int
iAppSpecific);
void Release();
}
ist als Aufzählungstyp WebMessageReturn definiert:
{
ReturnGood,
ReturnBad,
ReturnAbort
}
Abort bedeutet, die Verarbeitung zu beenden. Freigeben
Methoden bieten Diensten die Möglichkeit, Klasseninstanzen einfach zu löschen.
Da der Destruktor einer Klasseninstanz nur während der Garbage Collection aufgerufen wird, stellen Sie sicher, dass alle Klassen, die
teure Ressourcen (z. B. Datenbankverbindungen) verbrauchen, über eine Methode verfügen, die vor der Zerstörung aufgerufen werden kann.
Dies ist eine sehr gute Idee, diese Ressourcen freizugeben.
Service.Service-Namespace. Obwohl der Dienstcode in mehreren Dateien enthalten ist, müssen Benutzer nicht auf andere Dateien verweisen, da diese im selben Namespace enthalten sind.
Da die IWebMessage-Schnittstelle im Namen MSDNMessageService.Interface enthalten ist
Leerzeichen, sodass Thread-Klassen, die diese Schnittstelle verwenden, einen Schnittstellen-Namespace haben.
Dienstklasse
Wie bereits erwähnt, ist die Grundstruktur des Dienstes die von ServiceBase geerbte Klasse. Wichtige Methoden
einem Dienststeuerungsvorgang. Der Zweck der OnStart-Methode besteht darin, ein CWorker-Objekt zu erstellen,
und Die CWorker-Klasse erstellt wiederum ein CWorkerThread-Objekt und erstellt dann in diesem Objekt einen Thread, der die Dienstarbeit ausführt.
Die Laufzeitkonfiguration des Dienstes (und die Eigenschaften der CWorker- und CWorkerThread-Objekte) wird
in einer XML-basierten Konfigurationsdatei verwaltet. Sie hat denselben Namen wie die erstellte .exe-Datei, aber
Mit einem .cfg-Suffix. Das Konfigurationsbeispiel lautet wie folgt:
〈configuration〉
〈ProcessList〉
ProcessDefinition
ProcessName="Worker1"
ProcessDesc="Message Worker mit 2 Threads"
ProcessType="AppSpecific"
ProcessThreads="2"
InputQueue=".private$test_load1"
ErrorQueue=".private$test_error"〉
OutputList〉
〈OutputDefinition OutputName=".private$test_out11" /〉
〈OutputDefinition OutputName=".private$test_out12" /〉
〈/OutputList〉
〈/ProcessDefinition〉
〈ProcessDefinition
ProcessName="Worker2"
ProcessDesc="Montagearbeiter mit 1
Thread"
ProcessType="Assembly"
ProcessThreads="1"
InputQueue=".private$test_load2"
ErrorQueue=".private$test_error"〉
OutputList〉
OutputDefinition OutputName="C:MSDNMessageServiceMessage
Example.dll" /〉
OutputDefinition
OutputName="MSDNMessageService.Message
Sample.ExampleClass"/〉
〈/OutputList〉
〈/ProcessDefinition〉
〈/ProcessList〉
〈/Konfiguration〉
Der Zugriff auf diese Informationen wird über die Config
Manager-Klasse aus der System.Configuration-Assembly verwaltet. statisch
Die Get-Methode gibt eine Sammlung von Informationen zurück, die zum Abrufen einzelner Eigenschaften aufgelistet werden. Die Einstellungen dieser Eigenschaftssätze bestimmen die Laufzeiteigenschaften des Hilfsobjekts. Zusätzlich zu dieser
Konfigurationsdatei sollten Sie auch die Definition erstellen
Metadatei der XML-Dateistruktur und Referenzen
die Metadatei in der Konfigurationsdatei machine.cfg des Servers:
〈MetaData xmlns ="x-schema :CatMeta.xms"〉
〈DatabaseMeta InternalName="MessageService"〉
ServerWiring
Interceptor="Core_XMLInterceptor"/〉
〈Collection
InternalName="Process" PublicName="ProcessList"
PublicRowName="ProcessDefinition"
SchemaGeneratorFlags="EMITXMLSCHEMA"〉
Property InternalName="ProcessDesc" Type="String" /〉
Property
InternalName="ProcessType" Type="Int32" Default
Value="RoundRobin" 〉
〈Enum InternalName="RoundRobin" Value="0"/〉
〈Property InternalName="ProcessThreads"
Type="Int32"
DefaultValue="1" /〉
Property
InternalName="OutputName" Type="String" /〉
Operator="EQUAL" /〉
〈/Collection〉
Collection
InternalName="Output"
PublicName="OutputList"
PublicRowName="OutputDefinition"
SchemaGeneratorFlags="EMITXMLSCHEMA"〉
Property InternalName="OutputName" Type="String" Meta
Flags="PRIMARYKEY" /〉
QueryMeta InternalName="All"
MetaFlags="ALL" /〉
〈QueryMeta InternalName="QueryByFile"
CellName="__FILE"
Operator="EQUAL" /〉
〈/Collection〉
〈/DatabaseMeta〉
RelationMeta
PrimaryTable="Process"
PrimaryColumns="Prozessname"
ForeignTable="Output" ForeignColumns="ProcessName"
MetaFlags="USECONTAINMENT"/〉
〈/MetaData>
Hashtable-Sammlung verwendet, um den Namen von Typobjekten zu speichern.
Liste der Zahlenpaare. Hashtable unterstützt nicht
nur Aufzählungen, sondern ermöglicht auch die Abfrage von Werten über Schlüsselwörter. Innerhalb der Anwendung ist der XML-Prozessname
das einzige Schlüsselwort:
private Hashtable htWorkers = new Hashtable();
IConfigCollection
cWorkers = ConfigManager.Get("ProcessList", new
AppDomainSelector());
foreach (IConfigItem ciWorker in cWorkers)
{
WorkerFormatter
sfWorker = new WorkerFormatter();
sfWorker.ProcessName =
(string)ciWorker["ProcessName"];
sfWorker.ProcessDesc =
(string)ciWorker["ProcessDesc"];
sfWorker.NumberThreads =
(int)ciWorker["ProcessThreads"];
sfWorker.InputQueue =
(string)ciWorker["InputQueue"];
sfWorker.ErrorQueue =
(string)ciWorker["ErrorQueue"];
// 计算并定义进程类型
switch ((int)ciWorker["ProcessType"])
{
case 0:
sfWorker.ProcessType = WorkerFormatter.SFProcessType.
ProcessRoundRobin;
Pause;
Fall 1:
sfWorker.ProcessType
= WorkerFormatter.SFProcessType.
ProcessAppSpecific;
Pause;
Fall 2:
sfWorker.ProcessType = WorkerFormatter.SFProcessType.
ProcessAssembly;
Pause;
Standard:
neu werfen
Exception("Unbekannter Verarbeitungstyp");
}
// 执行更多的工作以读取输出信息
string sProcessName = (string)ciWorker["ProcessName"];
wenn
(htWorkers.ContainsKey(sProcessName))
throw new
ArgumentException("Prozessname muss eindeutig sein: "
+ sProcessName);
htWorkers.Add(sProcessName, new CWorker(sfWorker));
}
在这段代码中没有包含的主要信息是输出数据的获取.每一个进程定
义中都有一组相应的输出定义项.该信息是通过如下的简单查询读取的:
string sQuery = "SELECT * FROM OutputList WHERE ProcessName=" +
sfWorker.ProcessName + " AND Selector=appdomain://";
ConfigQuery QQuery = new ConfigQuery(sQuery);
IConfigCollection cOutputs = ConfigManager.Get("OutputList",
qQuery);
int iSize = cOutputs.Count, iLoop = 0;
sfWorker.OutputName = neu
string[iSize];
foreach (IConfigItem ciOutput in cOutputs)
sfWorker.OutputName[iLoop++] = (string)ciOutput["OutputName"];
CWorkerThread und Cworker操作进行调用.由于 Hashtable中引用了每一个
CWorker对象,因此需
要枚举 Hashtable的内容,以调用适当的服务控制方法:
foreach (CWorker cWorker in
htWorkers.Values)
cWorker.Start();
CWorker 对象上的相应方法来执行操作的.
Stop、Pause 和 Continue
Klicken Sie auf CWorkerThread
助对象引用的 Service类相似,CWorker 使用 ArrayList(简单的动态数
组)来维护线程对象的列表。
以上就是C#消息队列应用程序 -1的内容,更多相关文章请关注PHP中文网(m.sbmmt.com)!