はい、可能です。プロキシオブジェクトをアプリケーション全体に見えるようにすることができます。または、シンプルさのためにシングルトンクラスにラップすることができます(私の優先オプション)。ただし、サービスのプロキシを再利用する場合は、チャネルの障害を処理する必要があります。
最初に、再利用するプロキシ(またはプロキシ)のインスタンスを保持するシングルトンクラス/キャッシュ/グローバル変数を作成します。
プロキシを作成するとき、あなたは内部チャネル
proxyInstance.InnerChannel.Faulted += new EventHandler(ProxyFaulted);
には障害発生イベントをサブスクライブし、その後ProxyFaultedイベントハンドラ内で、いくつかの再接続コードを配置する必要があります。 Faultedイベントは、サービスがドロップするか、アイドル状態だったために接続がタイムアウトすると発生します。 faultedイベントは、コンフィグレーションファイル内のバインディングでreliableSessionが有効になっている場合にのみ発生します(指定されていない場合、このデフォルトはnetTcpBindingで有効になります)。
編集:プロキシチャンネルを常に開いたままにしたくない場合は、チャンネルを使用するたびにチャンネルの状態をテストし、フォルトがあればプロキシを再作成する必要があります。チャネルに障害が発生すると、新しいチャネルを作成することはできません。
Edit2:チャネルを開いたままにして閉じるときの負荷の唯一の違いは、キープアライブパケットがサービスに送信され、たびに肯定応答されることです(これはチャネルフォルトイベントの背後にあります)。 100人のユーザーが、これが問題になるとは思わない。
もう1つの方法は、プロキシの作成を使用ブロックの内側に置くことです。ここでは、ブロックの最後(つまり、considered bad practice)でクローズ/廃棄されます。通話後にチャンネルを閉じると、サービスがまだ処理を終了していないため、アプリケーションがハングすることがあります。実際、サービスの呼び出しが非同期であったり、メソッドのサービス契約が一方向であったりしても、サービスが終了するまでチャンネル終了コードはブロックされます。ここで
はあなたが必要なものの裸の骨を持っている必要があり、単純なシングルトンクラスです:
public static class SingletonProxy
{
private CupidClientServiceClient proxyInstance = null;
public CupidClientServiceClient ProxyInstance
{
get
{
if (proxyInstance == null)
{
AttemptToConnect();
}
return this.proxyInstance;
}
}
private void ProxyChannelFaulted(object sender, EventArgs e)
{
bool connected = false;
while (!connected)
{
// you may want to put timer code around this, or
// other code to limit the number of retrys if
// the connection keeps failing
AttemptToConnect();
}
}
public bool AttemptToConnect()
{
// this whole process needs to be thread safe
lock (proxyInstance)
{
try
{
if (proxyInstance != null)
{
// deregister the event handler from the old instance
proxyInstance.InnerChannel.Faulted -= new EventHandler(ProxyChannelFaulted);
}
//(re)create the instance
proxyInstance = new CupidClientServiceClient();
// always open the connection
proxyInstance.Open();
// add the event handler for the new instance
// the client faulted is needed to be inserted here (after the open)
// because we don't want the service instance to keep faulting (throwing faulted event)
// as soon as the open function call.
proxyInstance.InnerChannel.Faulted += new EventHandler(ProxyChannelFaulted);
return true;
}
catch (EndpointNotFoundException)
{
// do something here (log, show user message etc.)
return false;
}
catch (TimeoutException)
{
// do something here (log, show user message etc.)
return false;
}
}
}
}
私はそれが役立ちます:)
プロキシを使用しているアプリケーションの種類 - スマートクライアントまたはウェブ? –