ホームページ  >  記事  >  バックエンド開発  >  C# メッセージ キュー アプリケーション-2

C# メッセージ キュー アプリケーション-2

黄舟
黄舟オリジナル
2016-12-17 16:59:101286ブラウズ

この配列内に、CWorker クラスは CWorkerThread クラスの実装
を作成します。 Cワーカースレッド クラス (後述) は、継承する必要がある抽象クラスです。エクスポートされた
クラスは、メッセージの処理方法を定義します。
aThreads = new ArrayList(); (int idx=0; idx{
WorkerThreadFormatter wfThread = new WorkerThreadFormatter();
wfThread.PROcessName = sfWorker.ProcessName; wfThread.ProcessDesc = sfWorker.ProcessDesc; wfThread.ThreadNumber = idx;
wfThread.InputQueue = sfWorker.InputQueue
wfThread.ErrorQueue; sfWorker.ErrorQueue;
wfThread.OutputName = sfWorker.OutputName; // 補助タイプを定義し、補助スレッド構造体
CWorkerThread wtBase
スイッチに挿入します。 (sfWorker.ProcessType)
{
の場合 WorkerFormatter.SFProcessType.ProcessRoundRobin:
wtBase = new CWorkerThreadRoundRobin(this, wfThread);
ブレーク
ケース; WorkerFormatter.SFProcessType.ProcessAppSpecific:
wtBase = new CWorkerThreadAppSpecific(this, wfThread);
break; WorkerFormatter.SFProcessType.ProcessAssembly:
wtBase = new CWorkerThreadAssembly(this, wfThread)
デフォルト:
; throw new Exception("Unknown Processing Type");
}
// 配列への呼び出しを追加します
aThreads.Insert(idx, wtBase);
}

すべてのオブジェクトが作成されたら、各スレッド オブジェクトの Start メソッドを呼び出してそれらを開始できます。 cThread in aThreads)
cThread.Start();

Stop、Pause、Continue メソッドは、foreach ループ内で同様の操作を実行します。
Stop メソッドには次のガベージ コレクション操作があります。

GC.SuppressFinalize(this);


Stopメソッド
を明示的に呼び出さなくてもオブジェクトを正しく終了できるように、クラスデストラクター内でStopメソッドが呼び出されます。 Stop が呼び出された場合 メソッドを使用する場合、
コンストラクターを解析する必要はありません。 SuppressFinalize メソッドは、オブジェクトの Finalize メソッド (コンストラクターの実際の実装) が呼び出されるのを防ぎます。

CWorkerThread抽象クラス

CWorkerThreadはCWorkerThreadAppSpecifc、CWorkerThread

RoundRobin、 CWorkerThreadAssembly によって継承された抽象クラス。メッセージをどのように処理するかに関係なく、キューの処理のほとんどは同じであるため、CWorkerThread クラスはこの機能を提供します。

このクラスは、リソースを管理し、メッセージを処理するための抽象メソッド (実際のメソッドに置き換える必要があります) を提供します。

クラスの作業は、Start、Stop、Pause、Continue メソッドを通じて再び実装されます。
入力キューとエラーキューは Start メソッドで参照されます。存在する .NET Framework では、メッセージは System によって処理されます。

Messaging 名前空間:

// キューを開いて、デフォルトの読み取りおよび書き込みプロパティを設定してみます。

MessageQueue mqInput = 新しい MessageQueue(sInputQueue);

mqInput.MessageReadPropertyFilter.Body = true;

mqInput.MessageReadPropertyFilter.AppSpecific = true; mqError = new MessageQueue(sErrorQueue);

// MSMQ COM を使用する場合は、フォーマッタを ActiveX に設定します。
mqInput.Formatter = 新しい ActiveXMessageFormatter();
mqError.Formatter = new ActiveXMessageFormatter();

メッセージ キュー参照が定義されると、実際の処理関数

(ProcessMessages と呼ばれる) 用のスレッドが作成されます。 .NET Framework では、次を使用します。 System.Threading
名前空間を使用すると、スレッド化を簡単に実装できます。
procMessage = new Thread(new ThreadStart(ProcessMessages));
procMessage.Start();

ProcessMessages 関数は、ブール値に基づく処理ループです。値が
False に設定されると、処理ループは終了します。したがって、スレッド オブジェクトの Stop このメソッドは、このブール値
値を設定するだけで、開いているメッセージ キューを閉じ、スレッドをメイン スレッドに結合します。
// サービス スレッドと処理スレッドを結合します
bRun = false;
procMessage.Join();

// 開いているメッセージキューを閉じる

mqInput.Close();
mqError.Close();

Pause メソッドは、処理スレッドを 0.5 秒スリープさせるブール値のみを設定します:

if (bPause)

Thread.Sleep(500);

最後に、それぞれの Start、Stop、 Pause メソッドと Continue メソッドは、抽象
OnStart、OnStop、OnPause、および OnContinue メソッド。これらの抽象メソッドは、
を実装するクラスに、必要なリソースをキャプチャおよび解放するためのフックを提供します。

ProcessMessages ループは次の基本構造を持っています:
●メッセージを受信します。
● メッセージの受信が成功すると、抽象 ProcessMessage メソッドが呼び出されます。

●ReceiveまたはProcessMessageが失敗した場合、Messageをエラーキューに送信します。

Message mInput;
try
{
// キューから読み取り、1 秒待ちます
mInput = mqInput.Receive(new TimeSpan(0,0,0,1));
}
catch (MessageQueueException) mqe)
{
// メッセージを null に設定します
mInput = null
// エラー コードをチェックして、タイムアウトしたかどうかを確認します。
if (mqe.ErrorCode != (-1072824293) ) //0xC00E001B
{
// タイムアウトしない場合は、エラーを発行し、エラー番号を記録します
LogError("Error: " + mqe.Message)
throw mqe;
}
}
if (mInput != null)
{
// 処理対象のメッセージを取得し、メッセージ処理の抽象メソッドを呼び出します
try
{
ProcessMessage(mInput)
}
// 既知の例外ステータスを持つエラーをキャプチャします
catch (CWorkerThreadException ex)
{
ProcessError(mInput, ex.Terminate);
}
// 未知の例外をキャッチして Terminate を呼び出す
catch
{
ProcessError(mInput, true);
}
}

ProcessError メソッドは、エラー メッセージをエラー キューに送信します。さらに、次のような事態にもつながる可能性があります。
例外を送信してスレッドを終了します。 ProcessMessage メソッドが終了エラーまたは CWorker
ThreadException タイプをスローした場合にこれが行われます。

CworkerThread エクスポート クラス

CWorkerThread から継承するクラスは、OnStart、OnStop、On
Pause、OnContinue、および ProcessMessage メソッド。 OnStart メソッドと OnStop メソッドは、処理リソースを取得および解放します。 OnPause と OnContinue メソッドにより、これらのリソースの一時的な解放と再取得が可能になります。 ProcessMessage メソッドはメッセージを処理し、失敗イベントが発生したときに
を発生させる必要があります。 CWorkerThreadException 例外。

CWorkerThread コンストラクターは実行時パラメーターを定義するため、派生クラスは基本クラス

Constructor:

public を呼び出す必要があります。 CWorkerThreadDerived(CWorker v_cParent, WorkerThread
Formatter v_wfThread)
:base (v_cParent, v_wfThread) {}

エクスポートされたクラスは、別のキューにメッセージを送信するか、コンポーネントのメソッドを呼び出すという 2 種類の処理を提供します。メッセージの受信と送信の両方の実装では、ループ手法またはアプリケーション オフセット (維持) が使用されます。

どのキューを使用するかを決定する要素として、メッセージ AppSpecific プロパティを残しておきます。このシナリオの構成ファイル

には、キュー パスのリストが含まれている必要があります。 OnStart と OnStop メソッド
は、次のキューへの参照を開いたり閉じたりする必要があります。
iQueues = wfThread.OutputName.Length;
mqOutput = new MessageQueue[iQueues];
for (int idx=0; idx{
mqOutput[idx] = new MessageQueue(wfThread.OutputName[idx]);
mqOutput[idx].Formatter = new ActiveXMessageFormatter();
}

これらのシナリオでは、メッセージの処理は簡単で、必要な出力キューにメッセージを送信します。
loopの場合、この処理は、

try

{
mqOutput[iNextQueue].Send(v_mInput);
}
catch (例外例)
{
// エラーの場合は強制終了例外
throw new CWorkerThreadException(ex.Message, true);
// 次のキュー番号を計算します
iNextQueue++;
iNextQueue %= iQueues; メッセージパラメータを指定してコンポーネントを呼び出す後者の方法の方が興味深いです。プロセスメッセージ
メソッドは、IWebMessage インターフェイスを使用して .NET コンポーネントを呼び出します。 OnStart メソッドと OnStop メソッドは、このコンポーネントへの参照を取得および解放します。

このソリューションの構成ファイルには、完全なクラス名と、クラスが配置されているファイルの
場所の 2 つの項目が含まれている必要があります。 IWebMessage インターフェイスの定義に従って、コンポーネント上で呼び出します。 処理方法。

オブジェクト参照を取得するには、Activator.CreateInstanceメソッドを使用する必要があります。この手紙
ナンバーは組み立て式となります。ここではアセンブリファイルのパスとクラス名からエクスポートされます。
オブジェクト参照が取得されると、それは適切なインターフェイスに配置されます:

private IWebMessage iwmSample;

プライベート文字列 sFilePath、sTypeName; アセンブリのパスと型名を保存します
sFilePath = wfThread.OutputName[0]; wfThread.OutputName[1];

// 必要なオブジェクトへの参照を取得します

Assembly asmSample = Assembly.LoadFrom(sFilePath);
Type typSample = asmSample.GetType(sTypeName);
object objSample = Activator.CreateInstance(typSample);
// オブジェクトに必要なインターフェイスを定義します
iwmSample = (IWebMessage)objSample;

オブジェクト参照を取得した後、ProcessMessage メソッドは IWebMessage インターフェイスの
Process メソッドを呼び出します。
WebMessageReturn wbrSample;
try
{
// メソッド呼び出しのパラメータを定義
string sLabel = v_mInput.Label;
文字列 sBody = (文字列)v_mInput.Body; iAppSpecific = v_mInput.AppSpecific;
// メソッドを呼び出し、戻りコードを取得します
wbrSample = iwmSample.Process(sLabel, sBody, iAppSpecific)
}
catch; (InvalidCastException ex)
{
// メッセージ内容にエラーが発生した場合、非終了例外を強制的に発行する
throw new CWorkerThreadException(ex.Message, false)
}
catch (例外 ex);
{
// アセンブリが間違って呼び出された場合は、強制終了例外を発生させます
throw new CWorkerThreadException(ex.Message, true);
}
//エラーがない場合は、オブジェクト呼び出しの戻りステータスを確認します。
switch (wbrSample)
{
case WebMessageReturn.ReturnBad:
throw new CWorkerThreadException
(「メッセージを処理できません: マークされたメッセージ bad", false);
case WebMessageReturn.ReturnAbort:
throw new CWorkerThreadException
(「メッセージを処理できません: プロセス terminated", true);
default:
break;
}

提供されたサンプル コンポーネントは、メッセージ本文をデータベース テーブルに書き込みます。重大なデータベース エラーがキャプチャされた場合は、

エラー。プロセスを終了することもできますが、ここではメッセージをエラー メッセージ
としてマークするだけです。

この例で作成されたクラス インスタンスは高価なデータベース リソースを取得および保持する可能性があるため、OnPause メソッドと OnContinue メソッドを使用してオブジェクト参照を解放および再取得します。


検出デバイス

すべての優れたアプリケーションと同様に、検出デバイスはアプリケーションの

ステータスを監視するために使用されます。 。 NET Framework により、イベント ログ、パフォーマンス カウンター、および Windows 管理インスツルメンテーション (WMI) の統合が大幅に簡素化されます。 ) を申請プロセスに追加します。メッセージング アプリケーションは、System.Diagnostics アセンブリからのタイム ログとパフォーマンス カウンターを使用します。


ServiceBaseクラスでは、イベントログを自動的に有効にすることができます。さらに、ServiceBase
EventLog メンバーは、アプリケーション イベント ログへの書き込みをサポートしています。
EventLog.WriteEntry(sMyMessage, EventLogEntryType.Information);

アプリケーション ログではなくイベント ログに書き込むアプリケーションの場合、EventLog リソースへの参照を簡単に作成して取得することができます (「」で説明されています)。 CWorker クラスで行うのと同じ)、
WriteEntry メソッドを使用してログ エントリを記録できるようになります。
private EventLog cLog;

string sSource = ServiceControl.ServiceControlName

string sLog = "アプリケーション"; ソースが存在するかどうかを確認し、存在しない場合はソースを作成します
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);
// ログ オブジェクトを作成し、現在定義されているソースを参照します
cLog = new EventLog();
cLog.Source = sSource
// 作成が成功したことを示すエントリをログに書き込みます。
cLog.WriteEntry("Created fully", EventLogEntryType.Information);

.NET Framework はパフォーマンス カウンターを大幅に簡素化します。メッセージング アプリケーションは、メッセージを追跡するために、各処理スレッド、スレッド エクスポート
のユーザー、およびアプリケーション全体にカウンターを提供します。
メッセージの数と 1 秒あたりに処理されるメッセージの数。この機能を提供するには、パフォーマンス カウンター
のクラスを定義し、対応するカウンター インスタンスをインクリメントする必要があります。

パフォーマンスカウンターのカテゴリーはサービスのOnStartメソッドで定義されています。これらのカテゴリは、メッセージの総数と 1 秒あたりに処理されるメッセージの数という 2 つのカウンタを表します。

CounterCreationData[] cdMessage = 新しい CounterCreationData[2];
cdMessage[0] = new CounterCreationData("メッセージ数/合計", "合計
メッセージ数 処理されました",
PerformanceCounterType.NumberOfItems64);

cdMessage[1] = 新しい CounterCreationData("メッセージ数/秒",

"1 秒間に処理されたメッセージ数",
PerformanceCounterType.RateOfChangePerSecond32);
PerformanceCounterCategory.Create("MSDN メッセージ サービス", "MSDN
Message Service Counters", cdMessage);

パフォーマンス カウンター カテゴリが定義されると、アクセスするための PerformanceCounter オブジェクトが作成されます。
カウンターインスタンス機能について質問します。 PerformanceCounter オブジェクトには、カテゴリ、カウンター名、およびオプションのインスタンス名が必要です。ヘルパー プロセスの場合、xml ファイルのプロセス名が使用されます。コードは次のとおりです。
pcMsgTotWorker = new PerformanceCounter("MSDN メッセージ サービス",
"メッセージ/合計", sProcessName);
pcMsgSecWorker = new PerformanceCounter("MSDN メッセージ サービス",
"メッセージ数/秒", sProcessName);

pcMsgTotWorker.RawValue = 0;

pcMsgSecWorker.RawValue = 0;

カウンター値をインクリメントするには、次のメソッドを呼び出します。

pcMsgTotWorker.IncrementBy(1);
pcMsgSecWorker.IncrementBy(1);

最後に、サービスが終了したら、インストールされているパフォーマンス カウンター カテゴリをシステムから削除する必要があります:

PerformanceCounterCategory.Delete("MSDN Message Service") ;

パフォーマンスカウンターは.NET Frameworkで動作するため、特別なサービスを実行する必要があります。
このサービス (PerfCounterService) は共有メモリを提供します。カウンタ情報は共有
メモリに書き込まれ、パフォーマンス カウンタ システムによって読み取られます。

インストール

終了する前に、インストールと、installutil.exe という
インストール ツールについて簡単に紹介しましょう。このアプリケーションは Windows サービスは、installutil.exe
を使用してインストールする必要があります。したがって、System.Configuration.Install からのものを使用する必要があります。 アセンブリで継承されたインストーラークラス
:
public class ServiceRegister: Installer
{
private ServiceInstaller serviceInstaller
private ServiceProcessInstaller; processInstaller;
public ServiceRegister()
{
// サービスインストーラーを作成する
serviceInstaller = new ServiceInstaller();
serviceInstaller.StartType = ServiceStart.Manual;
serviceInstaller.ServiceName = ServiceControl.ServiceControl
名前;
serviceInstaller.DisplayName = ServiceControl.ServiceControl
Desc;
Installers.Add(serviceInstaller)
// プロセスインストーラーを作成します
processInstaller = new ServiceProcessInstaller();
processInstaller.RunUnderSystemAccount = true;
Installers.Add(processInstaller);
}
}

このクラスの例に示すように、Windows サービスの場合、サービスとサービス プロセスはそれぞれ、サービスを実行するアカウントを定義するインストーラーを必要とします。他のインストーラーではイベント ログを登録でき、
パフォーマンスカウンターとその他のリソース。

概要

この .NET Framework アプリケーションの例からわかるように、以前は Visual C++

プログラマーのみが可能であったアプリケーションが、単純なオブジェクト指向プログラムを使用して実装できるようになりました。排気
C# に重点を置いていますが、この記事で説明する内容は Visual Basic および
新しい .NET にも当てはまります。 このフレームワークを使用すると、開発者は任意のプログラミング言語を使用して、強力でスケーラブルな Windows アプリケーションとサービスを作成できます。

新しい .NET Framework は、プログラミングの可能性を簡素化し拡張するだけでなく、

忘れられがちなアプリケーション計測デバイス (パフォーマンス監視カウンターやイベント ログ通知など) を簡単に組み込むことも可能にします。

アプリに組み込まれています。ここのアプリケーションは Windows Management Detection Devices
(WMI) を使用しませんが、.NET Framework も同様に適用できます。

上記は C# Message Queuing Application-2 の内容です。その他の関連記事については、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。