Résoudre les problèmes liés aux services répartiteurs
S’applique à : Visual Studio 2019 et versions ultérieures
Cet article présente des suggestions de résolution des problèmes et des solutions possibles pour plusieurs problèmes courants qui peuvent se produire lorsque vous essayez d’obtenir un service réparti dans le Kit de développement logiciel (SDK) Visual Studio.
Les services réparti peuvent échouer de différentes manières. Une technique utile pour démarrer votre investigation consiste à vérifier le journal d’activité Visual Studio, qui journalise souvent les erreurs ou les avertissements lorsque les choses se passent avec des services réparti.
Problèmes lors de la demande d’un service
Peut-être que le défi le plus courant avec les services répartits est de comprendre le résultat ou l’exception qu’ils obtiennent d’un appel à IServiceBroker.GetProxyAsync ou IServiceBroker.GetPipeAsync. Un IServiceBroker résumé intentionnel supprime les préoccupations relatives à l’emplacement et à la façon dont un service réparti peut être activé. Mais quand les choses vont mal, il devient nécessaire d’explorer plus en détail pour diagnostiquer et corriger le problème.
Aucun service
Le résultat d’une demande de service peut être null
lorsque l’une des conditions suivantes est remplie :
- Le service demandé n’est pas inscrit. L’auteur du service réparti doit l’inscrire avec ou avec ProvideBrokeredServiceAttribute un fichier .pkgdef créé manuellement.
- Le service demandé est inscrit avec la configuration qui n’expose pas le service à ce client. L’étendue par défaut est ServiceAudience.Process, ce qui signifie que le service réparti ne peut être activé que lorsqu’il est profferé à partir du même processus que le client. Si le client se trouve dans un autre processus et que l’intention est que le service réparti soit disponible, modifiez l’inscription du service pour l’étendre ServiceAudience.
- Le service demandé est inscrit avec ServiceAudience.LiveShareGuest, une connexion Live Share existe, mais l’hôte n’offre pas ce service réparti ou la ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients propriété n’est pas définie
true
sur . Lors de l’exposition d’un service réparti sur Live Share, consultez Comment sécuriser un service réparti. - Le service demandé est inscrit, mais il manque des informations sur le package à initialiser afin que sa fabrique puisse être mise en place. L’attribut ProvideBrokeredServiceAttribute génère automatiquement l’inscription qui indique que le package auquel l’attribut a été appliqué afin que Visual Studio puisse charger ce package en fonction des besoins. Si l’attribut est appliqué au package incorrect ou si le fichier .pkgdef est créé manuellement, ces informations peuvent être manquantes ou inexactes.
- Le package Visual Studio chargé de proffer le service réparti lève pendant l’initialisation ou ne parvient pas à générer réellement cette fabrique de service. Consultez le journal d’activité Visual Studio pour obtenir la preuve d’un échec de chargement de package.
- La fabrique de service elle-même retourne
null
.
La demande de service lève une exception
Une demande de service peut lever une ServiceCompositionException exception lorsque la fabrique de service lève une exception. Cela signifie que tous les problèmes répertoriés ci-dessus aboutissent à un null
résultat qui ne s’applique pas. Examinez les détails de l’exception (y compris les exceptions internes) pour comprendre ce qui s’est passé et apporter les corrections nécessaires au client ou à la fabrique de services.
Vous obtenez un service local alors qu’un service distant était attendu
Une demande peut être remplie localement ou à distance, en fonction de l’inscription du service et de l’état actuel de Visual Studio. L’étendue par défaut est ServiceAudience.Process, ce qui signifie que le service réparti ne peut être activé que lorsqu’il est profferé à partir du même processus que le client.
Lorsqu’un service réparti doit être exposé à partir d’un hôte Live Share à un invité connecté, mais qu’il ServiceAudience est limité aux étendues locales, une demande d’un invité Live Share active le service réparti à partir de ce même ordinateur plutôt que de l’hôte. Mettez à jour l’inscription pour inclure ServiceAudience.LiveShareGuest pour exposer vos services répartis via Live Share. Vous devrez peut-être également définir ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients true
sur.
Important
L’inscription du service réparti doit exister sur l’invité Live Share et l’hôte pour prendre en charge l’invité lors de l’activation du service réparti à partir de l’hôte.
Lors de l’exposition d’un service réparti sur Live Share, consultez Comment sécuriser un service réparti.
Problèmes lors de la création d’un service
Un service réparti doit être fourni à partir d’une AsyncPackage classe, sauf si le service réparti est exporté via MEF, comme décrit dans Comment fournir un service réparti.
Une tentative de transfert d’un service réparti génère une exception si l’une de ces conditions est vraie :
- Le moniker du service en cours de proffer ne correspond pas exactement (nom et version) à un service inscrit.
- Une usine a déjà été profferée pour le même moniker de service.
Le résultat d’un appel à IBrokeredServiceContainer.Proffer est un IDisposable. Un service réparti devient indisponible pour les nouvelles demandes une fois cette valeur supprimée. Lorsque votre service réparti a une affinité spécifique à un contexte tel qu’une solution ouverte, il peut être approprié de placer uniquement le service réparti lorsque ce contexte est actif. Il n’est pas nécessaire de conserver et de supprimer cette valeur lorsque votre package est supprimé.
Suivi du RPC entre le client et le service
Une fois qu’une connexion entre le client et le service est établie, le suivi de leur communication peut être utile, en particulier lorsqu’ils se trouvent dans différents processus.
Par défaut, les traces de communications entre les services répartiteurs qui s’étendent sur les processus (de sorte que RPC s’applique) sont enregistrées dans les fichiers .svclog trouvés dans le %TEMP%\VSLogs
répertoire. Ces fichiers xml sont les mieux consultés avec la Visionneuse de trace de service. Cet outil peut ouvrir plusieurs fichiers .svclog à la fois et les assembler pour former un graphe multi-parties pour faciliter la compréhension du RPC entre le client et le service.
Un service réparti lui-même peut suivre directement pour l’ajouter à ces fichiers de trace .svclog , ce qui aide davantage les diagnostics du comportement du service réparti. Toutes les traces enregistrées %TEMP%\VSLogs
peuvent être collectées lorsque la commande « Signaler un problème » est appelée et que l’utilisateur choisit de partager des journaux.
Pour tracer vos propres messages afin qu’ils puissent être facilement découverts et combinés avec d’autres traces .svclog , votre code (qu’un service réparti ou non) puisse faire quelque chose comme suit :
// 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);
}
Vous myTraceSource
pouvez désormais l’utiliser pour le suivi, car il dispose des écouteurs appropriés ajoutés pour écrire vos traces dans un fichier .svclog . Si vous avez déjà un TraceSource utilisateur que vous souhaitez utiliser, passez-le à la RegisterLogSourceAsync méthode et ignorez le résultat, car les écouteurs seront ajoutés à votre existant TraceSource.
Lors du suivi à partir d’un service réparti qui sert un client distant, une activité est automatiquement affectée au ExecutionContext code dans lequel votre code s’exécute, ce qui permet à svclog d’être assemblé avec le journal svclog du client afin de voir une vue holistique à l’aide de la visionneuse de trace de service.