針對代理服務進行疑難解答
適用於: 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.AllowTransitiveGuestClients 為 true
。
提供服務時的問題
除非代理服務是透過MEF導出的,否則必須從AsyncPackage類別中提供代理服務,如如何提供代理服務中所述。
如果上述任一條件成立,嘗試提供代理服務將會擲回例外狀況:
- 所教授服務的Moniker與已註冊的服務完全不符(名稱和版本)。
- 已為相同的服務Moniker提供工廠。
通話 IBrokeredServiceContainer.Proffer 的結果為 IDisposable。 處置此值之後,代理服務就變成無法供新要求使用。 當您的代理服務具有某些內容的特定親和性時,例如開啟的解決方案,它可能只適合在該內容為使用中時提供代理服務。 處置套件時,不需要保留和處置此值。
追蹤客戶端與服務之間的 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);
}
myTraceSource
現在可用於追蹤,因為它已新增適當的接聽程式,以將追蹤寫入 .svclog 檔案。 如果您已經有 TraceSource 要使用的 ,請將它傳遞至 RegisterLogSourceAsync 方法,並捨棄結果,因為接聽程式將會新增至現有的 TraceSource。
從服務遠端用戶端的代理服務進行追蹤時,會自動將活動指派給您 ExecutionContext 的程式代碼執行,以便將 svclog 與用戶端的 svclog 合併在一起,以便使用 服務追蹤查看器來查看整體檢視。