Felsöka asynkrona tjänster
Gäller för: Visual Studio 2019 och senare versioner
I den här artikeln beskrivs felsökningsförslag och möjliga lösningar på flera vanliga problem som kan uppstå när du försöker få en asynkron tjänst i Visual Studio SDK.
Asynkrona tjänster kan misslyckas på olika sätt. En användbar teknik att starta undersökningen med är att kontrollera Visual Studio-aktivitetsloggen, som ofta loggar fel eller varningar när saker går snett med asynkrona tjänster.
Problem när du begär en tjänst
Den kanske vanligaste utmaningen med asynkrona tjänster är att förstå resultatet eller undantaget de får från ett anrop till IServiceBroker.GetProxyAsync eller IServiceBroker.GetPipeAsync. En IServiceBroker avsiktligt sammanfattar oron för var och hur en asynkron tjänst kan aktiveras. Men när saker går fel blir det nödvändigt att gå djupare för att diagnostisera och korrigera problemet.
Ingen tjänst
Resultatet av en tjänstbegäran kan vara null
när något av följande villkor är uppfyllda:
- Den begärda tjänsten är inte registrerad. Den asynkrona tjänstförfattaren bör registrera den med ProvideBrokeredServiceAttribute eller en handförfattare till .pkgdef-filen .
- Den begärda tjänsten är registrerad med konfiguration som inte exponerar tjänsten för den här klienten. Standardomfånget är ServiceAudience.Process, vilket innebär att den asynkrona tjänsten bara kan aktiveras när den erbjuds från samma process som klienten. Om klienten är i en annan process och avsikten är att den asynkrona tjänsten ska vara tillgänglig för den ändrar du tjänstregistreringen för att utöka dess ServiceAudience.
- Den begärda tjänsten är registrerad med ServiceAudience.LiveShareGuest, en Live Share-anslutning finns, men värden erbjuder inte den asynkrona ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients tjänsten eller så är egenskapen inte inställd på
true
. När du exponerar en asynkron tjänst via Live Share läser du Så här skyddar du en asynkron tjänst. - Den begärda tjänsten är registrerad men saknar information om vilket paket som ska initieras så att dess fabrik kan erbjudas. Attributet ProvideBrokeredServiceAttribute genererar automatiskt registrering som anger det paket som attributet tillämpades på så att Visual Studio kan läsa in paketet efter behov. Om attributet tillämpas på fel paket eller om .pkgdef-filen är författad för hand kan den här informationen saknas eller vara felaktig.
- Visual Studio-paketet som ansvarar för att erbjuda den asynkrona tjänsten genererar under initieringen eller på annat sätt misslyckas med att faktiskt erbjuda den tjänstfabriken. I Visual Studio-aktivitetsloggen finns bevis för ett paketinläsningsfel.
- Själva tjänstfabriken returnerar
null
.
Tjänstbegäran genererar ett undantag
En tjänstbegäran kan utlösa en ServiceCompositionException när tjänstfabriken utlöser ett undantag. Det innebär att alla problem som anges ovan som skulle leda till ett null
resultat inte gäller. Titta på undantagsinformationen (inklusive inre undantag) för att förstå vad som gick fel och göra eventuella nödvändiga korrigeringar av klienten eller tjänstfabriken.
Du får en lokal tjänst medan en fjärrtjänst förväntades
En begäran kan uppfyllas lokalt eller via fjärranslutning, beroende på tjänstregistreringen och det aktuella tillståndet för Visual Studio. Standardomfånget är ServiceAudience.Process, vilket innebär att den asynkrona tjänsten bara kan aktiveras när den erbjuds från samma process som klienten.
När en asynkron tjänst ska exponeras från en Live Share-värd till en ansluten gäst, men ServiceAudience är begränsad till lokala omfång, aktiverar en begäran från en Live Share-gäst den asynkrona tjänsten från samma dator i stället för värden. Uppdatera registreringen så att den visar ServiceAudience.LiveShareGuest dina asynkrona tjänster via Live Share. Du kan också behöva ange ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients till true
.
Viktigt!
Registrering för den asynkrona tjänsten måste finnas på både Live Share-gästen och värden för att stödja gästen i aktiveringen av den asynkrona tjänsten från värden.
När du exponerar en asynkron tjänst via Live Share läser du Så här skyddar du en asynkron tjänst.
Problem vid erbjudande av en tjänst
En asynkron tjänst måste erbjudas från en AsyncPackage klass om inte den asynkrona tjänsten exporteras via MEF, enligt beskrivningen i Så här tillhandahåller du en asynkron tjänst.
Ett försök att erbjuda en asynkron tjänst utlöser ett undantag om något av dessa villkor är sant:
- Monikern för tjänsten som erbjuds matchar inte exakt (namn och version) en tjänst som har registrerats.
- En fabrik har redan erbjudits för samma tjänstmoniker.
Resultatet av ett anrop till IBrokeredServiceContainer.Proffer är en IDisposable. En asynkron tjänst blir otillgänglig för nya begäranden när det här värdet har bortskaffats. När din asynkrona tjänst har specifik tillhörighet till en viss kontext, till exempel en öppen lösning, kan det vara lämpligt att endast erbjuda den asynkrona tjänsten när kontexten är aktiv. Det är inte nödvändigt att behålla och ta bort det här värdet när paketet tas bort.
Spåra RPC mellan klient och tjänst
När en anslutning mellan klient och tjänst har upprättats kan det vara användbart att spåra deras kommunikation, särskilt när de finns i olika processer.
Som standard registreras spårningar av kommunikation mellan asynkrona tjänster som omfattar processer (så att RPC gäller) i .svclog-filer som finns i %TEMP%\VSLogs
katalogen. Dessa XML-filer visas bäst med Service Trace Viewer. Det här verktyget kan öppna många .svclog-filer samtidigt och sammanfoga dem för att skapa en graf med flera parter för att göra det mycket enklare att förstå RPC mellan klient och tjänst.
En asynkron tjänst kan spåra direkt för att lägga till dessa .svclog-spårningsfiler , vilket ytterligare underlättar diagnostik av asynkrona tjänstbeteenden. Eventuella spårningar som sparats till %TEMP%\VSLogs
kan samlas in när kommandot "Rapportera ett problem" anropas och användaren väljer att dela loggar.
Om du vill spåra dina egna meddelanden så att de enkelt kan identifieras och kombineras med andra .svclog-spårningar kan din kod (oavsett om det är en asynkron tjänst eller inte) göra något liknande:
// 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
Kan nu användas för spårning eftersom lämpliga lyssnare har lagts till för att skriva dina spårningar till en .svclog-fil. Om du redan har en TraceSource du vill använda skickar du den till RegisterLogSourceAsync metoden och tar bort resultatet eftersom lyssnarna läggs till i din befintliga TraceSource.
När du spårar från en asynkron tjänst som hanterar en fjärrklient tilldelas en aktivitet automatiskt till ExecutionContext den kod som körs inom som gör att svclog kan sys ihop med klientens svclog för att se en holistisk vy med hjälp av Tjänstspårningsvisaren.