Pergunta

Eu tenho a 2 aplicação Silverlight que está consumindo um serviço WCF. Como tal, ele usa retornos de chamada assíncronos para todas as chamadas para os métodos do serviço. Se o serviço não estiver em execução, ou ele trava, ou a rede vai para baixo, etc, antes ou durante uma dessas chamadas, uma exceção é gerada como seria de esperar. O problema é, eu não sei como pegar essa exceção.

  • Porque é uma chamada assíncrona, não posso envolver minha começam chamada com um bloco try / catch e tê-lo pegar uma exceção que acontece depois que o programa mudou a partir desse ponto.

  • Uma vez que o proxy de serviço é gerada automaticamente, não posso colocar um bloco try / catch em cada função gerada que chama EndInvoke (onde a exceção, na verdade, mostra-se). Estas funções geradas também são cercados por código externo na pilha de chamadas, então não há nenhum outro lugar na pilha de colocar um try / catch quer.

  • Eu não posso colocar o try / catch em minhas funções de retorno, porque a exceção ocorre antes que iria obter chamado.

  • Há uma função Application_UnhandledException na minha App.xaml.cs, que capta todas as exceções não tratadas. Eu poderia usar isso, mas parece ser uma maneira confusa para fazê-lo. Eu prefiro reservar essa função para os erros verdadeiramente inesperados (aka bugs) e não acabar com código nesta função para cada circunstância que eu gostaria de lidar com de uma maneira específica.

Am I faltando uma solução óbvia? Ou eu estou preso usando Application_UnhandledException?

[Edit]
Como mencionado abaixo, a propriedade Erro é exatamente o que eu estava procurando. O que está me jogando para um loop é que o fato de que a exceção é lançada e parece ser não capturada, mas a execução é capaz de continuar. Ele aciona o evento Application_UnhandledException e provoca VS2008 para interromper a execução, mas continuar no depurador permite a execução para continuar. Não é realmente um problema, ele só parece estranho.

Foi útil?

Solução

I verificar a propriedade de erro dos argumentos do evento no manipulador de eventos método de serviço concluído. Eu não tive problemas com o evento manipulador não está sendo chamado. No caso em que o servidor vai para baixo, a chamada leva alguns segundos e depois volta com um ProtocolException na propriedade de erro.

Assumindo que você já tentou isso e seu retorno realmente nunca é chamado, você pode olhar para personalizar a classe proxy gerado. Consulte este artigo .

Outras dicas

uma discussão no fórum que estava falando sobre isso, e ele menciona que o melhor prática é usar a propriedade de erro. Entre esta discussão e minhas próprias experiências, isso é o que posso concluir:

  • No código normal .NET, as alças de classe proxy gerado a exceção corretamente, colocando a exceção na propriedade de erro em vez de jogá-lo.

  • No Silverlight, a classe proxy gerado define a propriedade de erro, mas não tratar a exceção completamente. A exceção é captado pelo depurador, que aparece a caixa de exceção com a mensagem "ProtocolException foi não tratada pelo código do usuário". Apesar dessa mensagem, a exceção não parece realmente fazê-lo para a função Application_UnhandledException.

Eu esperaria que isso é uma das coisas que eles vão corrigir na versão final.

Por enquanto, vou usar a propriedade de erro e apenas lidar com a execução depurador quebra. Se ficar muito chato, eu posso desligar a pausa na exceção para ProtocolException.

Você pode esquecer Application_UnhandledException em chamadas de retorno cliente asyn, razão pela qual:

Application_UnhandledException únicas exceções ateado fogo no segmento interface do usuário pode ser pego por Application.UnhandledExceptions

Isto significa ... não chamado a todos para uma chamada WCF assíncrona: -).

Verificar resposta detalhada da MSFT

http://silverlight.net/forums/t/21828.aspx

Olá, únicas exceções ateado fogo no segmento interface do usuário pode ser pego por Application.UnhandledExceptions. Não pode capturar exceções de outros tópicos. Você pode tentar isso para atirar problemas o problema: No Visual Studio, no menu Debug, escolha Exceções. Em seguida, verifique "Exceções Common Language Runtime". Isso fará com que a paragem depurador sempre que uma exceção é lançada. Mas note que este pode ser, por vezes, bastante irritante uma vez que mesmo se uma exceção já está preso. Você pode usar as caixas de seleção para filtrar as exceções que você quer pegar.

Boa notícia no meu caso é que lidar com a mensagem de erro apenas no call back serviço clietn é suficiente, se você não está depurando.

Graças

Braulio

OOpps ....

resposta errada Desculpe do meu lado (bem o cara MSFT não atingiu o serviço de resposta escrita retornos de chamada são chamados no mesmo segmento UI), a coisa é

Mais informações:

- In development even detaching from the debugger, this method is never reached. 
- On the production environment yes.

Meu palpite algo relacionado com as opções do Visual Studio e exceções interceptar.

Mais informações, neste segmento http://silverlight.net/forums/p/48613/186745.aspx# 186745

tema bastante interessante.

Com o Silverlight 3, o depurador Visual Studio pega essas exceções para que o manipulador de exceção - confusamente - nunca é alcançado. No entanto, ao executar o sem o depurador, o manipulador de exceção é chamado como o esperado. Eu acho que isso é ok, enquanto um está ciente disso. Eu admito que eu desperdiçado algumas horas tentando descobrir como furar o funcionamento interno do Silverlight / Wcf / Browser para chegar ao meu exceção. Não vá lá.

Eu não sou um canalizador, então eu decidi criar minha própria classe de serviço WCF que substitui algumas das funcionalidades do arquivo de classe "Reference.cs" que é gerado automaticamente pelo Visual Studio, então eu adicionei minha própria try / blocos catch para erros de comunicação de captura.

A classe eu criei é algo como isto:

public class myWCFService : MyWCFServiceClient
{

    protected override MyController.MyService.IMyWCFService CreateChannel()
    {
        return new MyWCFServiceClientChannel(this);
    }

}

private class MyWCFServiceClientChannel : ChannelBase<MyController.MyService.IMyWCFService>, MyController.MyService.IMyWCFService
{
    /// <summary>
    /// Channel Constructor
    /// </summary>
    /// <param name="client"></param>
    public MyWCFServiceClientChannel(System.ServiceModel.ClientBase<MyController.MyService.IMyWCFService> client) :
    base(client)
    {
    }
    /// <summary>
    /// Begin Call To RegisterUser
    /// </summary>
    /// <param name="memberInformation"></param>
    /// <param name="callback"></param>
    /// <param name="asyncState"></param>
    /// <returns></returns>
    public System.IAsyncResult BeginRegisterUser(MyDataEntities.MembershipInformation memberInformation, System.AsyncCallback callback, object asyncState)
    {               
        object[] _args = new object[1];
        _args[0] = memberInformation;
        System.IAsyncResult _result = base.BeginInvoke("RegisterUser", _args, callback, asyncState);
        return _result;               
    }
    /// <summary>
    /// Result from RegisterUser
    /// </summary>
    /// <param name="result"></param>
    /// <returns></returns>
    public MyDataEntities.MembershipInformation EndRegisterUser(System.IAsyncResult result)
    {
        try
        {
            object[] _args = new object[0];
            MyDataEntities.MembershipInformation _result = ((MyDataEntities.MembershipInformation)(base.EndInvoke("RegisterUser", _args, result)));
            return _result;
        }
         catch (Exception ex)
        {
            MyDataEntities.MembershipInformation _result = new MyDataEntities.MembershipInformation();
            _result.ValidationInformation.HasErrors = true;
            _result.ValidationInformation.Message = ex.Message;
            return _result;
        }
    }
}

Usando um costume gerador WCF Proxy é uma solução boa para lidar com exceções assíncronas em Silver-light.Click aqui para código de download de fonte.

Com XNA no WP7, eu descobri que eu não tinha escolha, mas para adicionar manualmente try / catch ao * functionName * () métodos vários assíncrona End; nada mais que eu tentei iria impedir a falha e desligamento do aplicativo quando o servidor não estava disponível. É uma chatice ter que atualizar manualmente o código quando um serviço alterações.

Estou surpreso este não é um problema maior, já que não parece haver nenhuma outra maneira de capturar essas exceções no WP7 usando XNA, mas suponho que isso só diz mais sobre quantas (== não muitas) pessoas são tentando fazer isso do que qualquer outra coisa. Se eles iriam apenas fazer slsvcutil.exe gerar métodos de sincronização que poderia facilmente pegar esses dentro de nosso próprio segmento de trabalho, mas infelizmente os tópicos piscina usa código de rosca gerados sem meios para capturar as exceções.

Para lidar com esta situação usar o TargetInvocationException. Isso irá capturar a exceção quando a rede está em baixo ou o serviço não está disponível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top