Solucionar problemas de serviços agenciados
Aplica-se a: Visual Studio 2019 e versões posteriores
Este artigo apresenta sugestões de solução de problemas e possíveis soluções para vários problemas comuns que podem ocorrer quando você tenta obter um serviço agenciado no SDK do Visual Studio.
Os serviços agenciados podem falhar de várias maneiras. Uma técnica útil para iniciar sua investigação é verificar o Log de Atividades do Visual Studio, que geralmente registra erros ou avisos quando as coisas dão errado com serviços agenciados.
Problemas ao solicitar um serviço
Talvez o desafio mais comum com os serviços agenciados seja entender o resultado ou a exceção que eles obtêm de uma chamada para IServiceBroker.GetProxyAsync ou IServiceBroker.GetPipeAsync. Um IServiceBroker abstrai intencionalmente as preocupações sobre onde e como um serviço agenciado pode ser ativado. Mas quando as coisas dão errado, torna-se necessário se aprofundar para diagnosticar e corrigir o problema.
Sem serviço
O resultado de uma solicitação de serviço pode ser null
quando qualquer uma das seguintes condições é verdadeira:
- O serviço solicitado não está registrado. O autor do serviço agenciado deve registrá-lo com ProvideBrokeredServiceAttribute um arquivo .pkgdef criado manualmente.
- O serviço solicitado é registrado com uma configuração que não expõe o serviço a esse cliente. O escopo padrão é ServiceAudience.Process, o que significa que o serviço agenciado só pode ser ativado quando é oferecido a partir do mesmo processo que o cliente. Se o cliente estiver em outro processo e a intenção for que o serviço agenciado esteja disponível para ele, altere o registro do serviço para expandir seu ServiceAudience.
- O serviço solicitado está registrado com ServiceAudience.LiveShareGuest, existe uma conexão do Live Share, mas o host não oferece esse serviço agenciado ou a ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients propriedade não está definida como
true
. Ao expor um serviço agenciado pelo Live Share, examine Como proteger um serviço agenciado. - O serviço solicitado está registrado, mas não há informações sobre qual pacote inicializar para que sua fábrica possa ser oferecida. O ProvideBrokeredServiceAttribute atributo gera automaticamente o registro que indica o pacote ao qual o atributo foi aplicado para que o Visual Studio possa carregar esse pacote conforme necessário. Se o atributo for aplicado ao pacote errado ou o arquivo .pkgdef for criado manualmente, essas informações podem estar ausentes ou imprecisas.
- O pacote do Visual Studio responsável por oferecer o serviço agenciado é lançado durante a inicialização ou, de outra forma, falha ao oferecer essa fábrica de serviços. Verifique o Log de Atividades do Visual Studio para obter evidências de uma falha de carregamento do pacote.
- A própria fábrica de serviços retorna
null
.
A solicitação de serviço gera uma exceção
Uma solicitação de serviço pode gerar um ServiceCompositionException quando a fábrica de serviços gera uma exceção. Isso significa que todos os problemas listados acima que levariam a um null
resultado não se aplicam. Examine os detalhes da exceção (incluindo exceções internas) para entender o que deu errado e faça as correções necessárias no cliente ou na fábrica de serviços.
Você obtém um serviço local enquanto um remoto era esperado
Uma solicitação pode ser atendida local ou remotamente, dependendo do registro do serviço e do estado atual do Visual Studio. O escopo padrão é ServiceAudience.Process, o que significa que o serviço agenciado só pode ser ativado quando é oferecido a partir do mesmo processo que o cliente.
Quando um serviço agenciado deve ser exposto de um host do Live Share para um convidado conectado, mas está ServiceAudience limitado a escopos locais, uma solicitação de um convidado do Live Share ativará o serviço agenciado desse mesmo computador em vez do host. Atualize o registro para incluir ServiceAudience.LiveShareGuest a exposição de seus serviços agenciados no Live Share. Você também pode precisar definir ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients também true
.
Importante
O registro para o serviço agenciado deve existir no convidado do Live Share e no host para dar suporte ao convidado na ativação do serviço agenciado do host.
Ao expor um serviço agenciado pelo Live Share, examine Como proteger um serviço agenciado.
Problemas ao oferecer um serviço
Um serviço agenciado deve ser oferecido de uma AsyncPackage classe, a menos que o serviço agenciado seja exportado via MEF, conforme descrito em Como fornecer um serviço agenciado.
Uma tentativa de oferecer um serviço agenciado gerará uma exceção se qualquer uma destas condições for verdadeira:
- O apelido do serviço que está sendo oferecido não corresponde exatamente (nome e versão) a um serviço que foi registrado.
- Uma fábrica já foi oferecida para o mesmo apelido de serviço.
O resultado de uma chamada para IBrokeredServiceContainer.Proffer é um IDisposable. Um serviço agenciado fica indisponível para novas solicitações depois que esse valor é descartado. Quando o serviço agenciado tem afinidade específica com algum contexto, como uma solução aberta, pode ser apropriado oferecer o serviço agenciado apenas quando esse contexto estiver ativo. Não é necessário reter e descartar esse valor quando o pacote é descartado.
Rastreando RPC entre cliente e serviço
Uma vez estabelecida uma conexão entre cliente e serviço, rastrear sua comunicação pode ser útil, principalmente quando eles estão em processos diferentes.
Por padrão, os rastreamentos de comunicações entre serviços agenciados que abrangem processos (de modo que o RPC se aplica) são registrados em arquivos .svclog encontrados no %TEMP%\VSLogs
diretório. Esses arquivos xml são melhor exibidos com o Visualizador de Rastreamento de Serviço. Essa ferramenta pode abrir muitos arquivos .svclog de uma só vez e juntá-los para formar um grafo de várias partes para facilitar muito a compreensão do RPC entre o cliente e o serviço.
Um serviço agenciado em si pode rastrear diretamente para adicionar a esses arquivos de rastreamento .svclog , auxiliando ainda mais no diagnóstico do comportamento do serviço agenciado. Todos os rastreamentos salvos podem %TEMP%\VSLogs
ser coletados quando o comando "Relatar um problema" é invocado e o usuário opta por compartilhar logs.
Para rastrear suas próprias mensagens de modo que elas possam ser facilmente descobertas e combinadas com outros rastreamentos .svclog , seu código (seja um serviço agenciado ou não) pode fazer algo assim:
// 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);
}
O myTraceSource
agora pode ser usado para rastreamento, pois tem os ouvintes apropriados adicionados para gravar seus rastreamentos em um arquivo .svclog . Se você já tem um TraceSource que deseja usar, passe-o para o RegisterLogSourceAsync método e descarte o resultado, pois os ouvintes serão adicionados ao seu .TraceSource
Ao rastrear de um serviço agenciado que atende a um cliente remoto, uma atividade é atribuída automaticamente ao ExecutionContext que seu código executa que permite que o svclog seja compilado com o svclog do cliente para ver uma exibição holística usando o Visualizador de Rastreamento de Serviço.