次の方法で共有


ブローカー サービスのトラブルシューティング

適用対象: Visual Studio 2019 以降のバージョン

この記事では、Visual Studio SDK でサービスを取得しようとしたときに発生する可能性のあるいくつかの一般的な問題に対するトラブルシューティングの提案と考えられる解決策について説明します。

仲介型サービスは、さまざまな理由でエラーになる可能性があります。 調査を開始する際に役立つ方法は、Visual Studio のアクティビティ ログを確認することです。このログには、仲介型サービスで問題が発生したときにエラーや警告が記録されることがよくあります。

サービスを要求するときの問題

仲介型サービスの最も一般的な課題はおそらく、IServiceBroker.GetProxyAsync または IServiceBroker.GetPipeAsync の呼び出しから得られる結果または例外を理解することです。 IServiceBroker では、仲介型サービスをアクティブ化する場所と方法に関する懸念が意図的に抽象化されています。 しかし、問題が発生した場合は、問題を診断して修正するために、詳細情報が必要になります。

圏外

サービス要求の結果は、次のいずれかの条件に該当する場合、null になる場合があります。

  • 要求されたサービスが登録されていない。 ブローカー サービスの作成者は、 ProvideBrokeredServiceAttribute または手動で作成された .pkgdef ファイルに登録する必要があります。
  • 要求されたサービスが、このクライアントにサービスを公開しない構成で登録されている。 既定のスコープは ServiceAudience.Process です。これは、仲介型サービスをアクティブ化できるのは、クライアントと同じプロセスから提供されている場合のみであることを意味します。 クライアントが別のプロセスにあり、仲介型サービスを使用できるようにすることが目的である場合は、サービス登録を変更して ServiceAudience を拡張します。
  • 要求されたサービスが ServiceAudience.LiveShareGuest で登録されており、Live Share 接続が存在するが、ホストがその仲介サービスを提供していないか、ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients プロパティが true に設定されていない。 Live Share 経由で仲介型サービスを公開する場合は、仲介型サービスをセキュリティで保護する方法に関する記事を確認してください。
  • 要求されたサービスは登録されているが、初期化するパッケージに関する情報がないため、ファクトリを提供できない。 ProvideBrokeredServiceAttribute 属性は、この属性が適用されたパッケージを示す登録を自動的に生成し、Visual Studio が必要に応じてそのパッケージを読み込むことができるようにします。 属性が間違ったパッケージに適用されているか、 .pkgdef ファイルが手動で作成されている場合、この情報が見つからないか不正確である可能性があります。
  • 仲介型サービスを提供する役目を持つ Visual Studio パッケージが、初期化中に例外をスローするか、実際にそのサービス ファクトリを提供することに失敗している。 Visual Studio のアクティビティ ログで、パッケージの読み込みに失敗している証拠がないかを確認してください。
  • サービス ファクトリ自体が null を返している。

サービス要求が例外をスローする

サービス要求は、サービス ファクトリが例外をスローすると、ServiceCompositionException をスローします。 これは、null の結果につながる上記のすべての問題は該当しないことを意味します。 例外の詳細 (内部例外を含む) を調べて、問題の原因を理解し、クライアントまたはサービス ファクトリを必要に応じて修正します。

リモート サービスが想定されていたときにローカル サービスを取得する

要求は、サービスの登録と Visual Studio の現在の状態に応じて、ローカルまたはリモートで処理される場合があります。 既定のスコープは ServiceAudience.Process です。これは、仲介型サービスをアクティブ化できるのは、クライアントと同じプロセスから提供されている場合のみであることを意味します。

仲介型サービスを Live Share ホストから接続されたゲストに公開する必要があるが、ServiceAudience がローカル スコープに制限されている場合、Live Share ゲストからの要求によって、ホストではなく同じマシンからブローカー サービスがアクティブ化されます。 登録を更新して ServiceAudience.LiveShareGuest を含めるようにし、仲介型サービスを Live Share 経由で公開します。 場合によっては、ProvideBrokeredServiceAttribute.AllowTransitiveGuestClientstrue に設定する必要があります。

重要

仲介型サービスの登録は、ゲストがホストからブローカー サービスをアクティブ化することをサポートするために、Live Share ゲストとホストの両方に存在する必要があります。

Live Share 経由で仲介型サービスを公開する場合は、仲介型サービスをセキュリティで保護する方法に関する記事を確認してください。

サービスを提供するときの問題

仲介型サービスは、仲介型サービスを提供する方法の説明に従って、仲介型サービスが MEF 経由でエクスポートされない限り、AsyncPackage クラスから提供する必要があります。

次のいずれかの条件が満たされている場合、仲介型サービスを提供しようとすると例外がスローされます。

  • 提供されるサービスのモニカーが、登録されているサービスと正確に一致しない (名前とバージョン)。
  • 同じサービス モニカーに対してファクトリが既に提供されている。

IBrokeredServiceContainer.Proffer の呼び出しの結果は IDisposable になります。 この値が破棄された後、仲介型サービスは新しい要求で使用できなくなります。 仲介型サービスがオープン ソリューションなどの一部のコンテキストに対して特定のアフィニティを持つ場合は、そのコンテキストがアクティブな場合にのみ仲介型サービスを提供することが適切な場合があります。 この値を保持し、パッケージが破棄されるときに、破棄する必要はありません。

クライアントとサービスの間の RPC のトレース

クライアントとサービスの間の接続が確立されると、特にそれらが異なるプロセスにある場合は、通信のトレースが役に立ちます。

既定では、プロセス (RPC が適用されるなど) にまたがるブローカー サービス間の通信のトレースは、%TEMP%\VSLogs ディレクトリにある .svclog ファイルに記録されます。 これらの xml ファイルは、サービス トレース ビューアーで最適に表示されます。 このツールでは、多数の .svclog ファイルを一度に開き、それらを結合してマルチパーティ グラフを形成し、クライアントとサービスの間の RPC をより簡単に理解できます。

ブローカー サービス自体は、これらの .svclog トレース ファイルに追加するために直接トレースでき、ブローカー サービスの動作の診断をさらに支援します。 "問題の報告" コマンドが呼び出され、ユーザーがログの共有を選択すると、%TEMP%\VSLogs に保存されたトレースが収集される可能性があります。

他の .svclog トレースと簡単に検出して結合できるように独自のメッセージをトレースするには、コード (ブローカー サービスかどうかに関係なく) 次のような処理を実行できます。

// Define your log's ID, a namespace-like fully qualified name.
// In general it is expected that you follow you team's assembly namespace.
// Also an optional parameter, the ServiceMoniker for your service
var myLogId = new LogId("Microsoft.SomeTeam.MyLogName", serviceId: null);

var requestedLevel = new LoggingLevelSettings(SourceLevels.Warning | SourceLevels.ActivityTracing);
var myLogOptions = new LoggerOptions(requestedLevel, PrivacyFlags.MayContainPrivateInformation);

TraceSource myTraceSource;
using (TraceConfiguration traceConfig = await TraceConfiguration.CreateTraceConfigurationInstanceAsync(serviceBroker, ownsServiceBroker: false, cancellationToken))
{
    myTraceSource = await traceConfig.RegisterLogSourceAsync(myLogId, myLogOptions, traceSource: null, cancellationToken);
}

トレースを .svclog ファイルに書き込む適切なリスナーが追加されているため、myTraceSourceをトレースに使用できるようになりました。 使用したい TraceSource が既にある場合は、それを RegisterLogSourceAsync メソッドに渡し、リスナーが既存の TraceSource に追加されるため、結果を破棄します。

リモート クライアントにサービスを提供する仲介型サービスからトレースする場合、アクティビティは、コードが実行されている ExecutionContext に自動的に割り当てられるため、サービス トレース ビューアーを使用して包括的なビューを表示するために、svclog をクライアントの svclog と結合できるようになります。

関連情報