none
Tipo de instancia, concorrencia e deadlock RRS feed

  • Pergunta

  • <!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:HyphenationZone>21</w:HyphenationZone> <w:PunctuationKerning/> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>PT-BR</w:LidThemeOther> <w:LidThemeAsian>X-NONE</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:DontVertAlignCellWithSp/> <w:DontBreakConstrainedForcedTables/> <w:DontVertAlignInTxbx/> <w:Word11KerningPairs/> <w:CachedColBalance/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="--"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]--> <!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-520092929 1073786111 9 0 415 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin-top:0cm; margin-right:0cm; margin-bottom:10.0pt; margin-left:0cm; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:Calibri; mso-fareast-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-fareast-language:EN-US;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:Calibri; mso-fareast-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-fareast-language:EN-US;} .MsoPapDefault {mso-style-type:export-only; margin-bottom:10.0pt; line-height:115%;} @page Section1 {size:595.3pt 841.9pt; margin:70.85pt 3.0cm 70.85pt 3.0cm; mso-header-margin:35.4pt; mso-footer-margin:35.4pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

    Ola a todos,

    Estou tendo um problema de deadlock num método da minha classe de serviço.

    Eu define a classe de serviço desta forma:
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]

    porem quando dois clientes acessão o mesmo método, a segunda requisição fica aguardando a primeira terminar. Com a configuração acima isto não se resolveria?

    terça-feira, 9 de março de 2010 17:54

Respostas

Todas as Respostas

  • Boas Marcio,

    Você pode ter problemas de concorrência se houverem várias requisições partindo da mesma instância do proxy.

    Mensagens partindo de proxies diferentes não devem interferir uma na outra, a menos que dentro da operação, você utiliza um mesmo recurso compartilhado, como objetos estáticos.
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 18:10
    Moderador

  • Deixa eu ver se entendi.

    Eu tenho uma tela que instancia um proxy, esta tela esta sendo usada em varios computadores. Ele considera isto o mesmo proxy ? É isto?
    Pois as telas são as mesmas porém em computadores diferentes.
    terça-feira, 9 de março de 2010 18:24
  • Boas Marcio,

    Não, se você tem uma instância do proxy em uma aplicação e você gera 5 threads utilizando aquela mesma instância para invocar as operações, você pode ter problemas de concorrência, já que todas as mensagens irão afunilar na mesma instância do lado do serviço.
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 18:26
    Moderador
  • Hummm, mas o que esta contecendo então no meu caso pois quando faço a segunda requisicção, ela fica aguardando a primeira teminar. Fiz um teste somente com um loop fazendo uma contagem para testar e confirmei isto. Quando inicio a segunda tela para fazer a contagem, ela fica aguardando a primeira terminar.

    veja:

    Servidor:

        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
        class _ServicoContador: IServico
        {
            double IContador.Contar(double pIntContador)
            {
                double d;
               
                for (d = 0; d < pIntContador; d++) { }

                return d;
            }


    Cliente


            private void btnContar_Click(object sender, EventArgs e)
            {
                txtResultado.Clear();
                          
                double dblResultado;

                dblResultado = SrvContador.Contar(double.Parse(txtValor.Text));
               
                txtResultado.Text = dblResultado.ToString();
            }




    terça-feira, 9 de março de 2010 18:35
  • Boas Marcio,

    Não veja nada demais neste código. Como você identifica que é um deadlock? Qual a mensagem de erro que está obtendo?
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 18:38
    Moderador
  • Na realidade eu executo o programinha duas vezes uma tela do lado da outra, então numa tela peço para contar até 1.000.000.000 e executo, logo em seguida executo a segunda para contar até 100. A contagem ate 100 é muito mais rápida do que 1.000.000.000 mas como eu iniciei a contagem do maior numero primeiro e logo em seguida a tela de 100, percebi que ela terminou a contagem somente depois que a contagem da primeira terminou ou seja a segunda tela ficou esperando a contagem da primeira terminar.
    terça-feira, 9 de março de 2010 18:45
  • Boas Marcio,

    Tentei reproduzir aqui, e tudo corre sem problemas. Com duas aplicações que consomem o mesmo serviço, e mesmo durante a contagem de 1.000.000.000, consiga que a segunda aplicação rode e conte até 100.
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 19:01
    Moderador
  • Aqui também roda sem problemas porem a segunda tela que é muito mais rápida que a primeira, só terminou de contar depois que a primeira terminou.
    terça-feira, 9 de março de 2010 19:03
  • Boas Marcio,

    Bem, aqui não. A segunda sempre retorna antes, por contar somente até 100. Qual o código que está utilizando na configuração do serviço?
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 19:05
    Moderador


  • Host:

            public void IniciarServidorHost(string strEndereco)
           {
            
                _Binding = new NetTcpBinding();

                ConfigurarBinding(_Binding);

                _BindingMex = MetadataExchangeBindings.CreateMexTcpBinding();
                _BindingMex.Name = "BindingMex";

                _HostPrincipal = new ServiceHost(typeof(_ServicoConatdor), new Uri[] { new Uri(strEndereco) });           
                _HostPrincipal.Description.Behaviors.Add(new ServiceMetadataBehavior());           
                _HostPrincipal.AddServiceEndpoint(typeof(IMetadataExchange), _BindingMex, "mexPrincipal");
             
             
                _HostPrincipal.AddServiceEndpoint(typeof(IContador), _Binding, "Contador");                       

             
                _HostPrincipal.Open();
            }


    Serviço:

        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
        class _ServicoContador: IServicoContador
        {


    Contrato:

        [ServiceContract(SessionMode = SessionMode.Required)]
        interface IContador
        {
            [OperationContract()]
            double Contar(double pIntContador);
        }



    Codigo:

            double IDepartamento.Contar(double pIntContador)
            {
                double d;
               
                for (d = 0; d < pIntContador; d++)
                {
                   
                }

                return d;
            }






    terça-feira, 9 de março de 2010 19:18
  • Boas Marcio,

    Exatamente como eu fiz aqui. Só notei que a interface do contrato (IContador) está diferente do que você mostra, que é IDepartamento.
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 19:29
    Moderador
  • É que eu fiz a aplicação de teste copiando as rotinas do meu servidor quente e ai esqueci de mudar, mas aqui esta correto.

    Será que voce pode me mandar o código do projetinho que voce fez ai para eu dar uma olhada?

    marcio.chiaveli@gmail.com
    terça-feira, 9 de março de 2010 19:32
  • Humm, conferi tudo e não vi diferença, vou continuar tentando e quando conseguir posto a solução.

    T+ e obrigado.
    terça-feira, 9 de março de 2010 20:02
  • Boas Marcio,

    Algum tipo de exceção é lançado?
    http://www.israelaece.com
    terça-feira, 9 de março de 2010 21:54
    Moderador
  • Não nenhum, só que o segundo processo fica aguardando o primeiro terminar.
    quinta-feira, 11 de março de 2010 18:14
  • Boas Marcio,

    Percebi que o seu serviço está hospedado no Windows Forms. Sendo assim, dá uma lida neste artigo: http://www.israelaece.com/post/Host-de-Servicos-em-Aplicacoes-Windows.aspx
    http://www.israelaece.com
    • Marcado como Resposta marcio.chiaveli quinta-feira, 11 de março de 2010 20:10
    quinta-feira, 11 de março de 2010 18:34
    Moderador
  • Era isto mesmo Israel, eu criei o meu host na main da minha aplicação antes de executar e criar o form principal e deu certo, veja como ficou:

    namespace Servidor
    {
        static class Program
        {
            private static ServiceHost _Servidor;

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                IniciarHost();
                Application.Run(new Servidor());
            }

            private static void IniciarHost()
            {
                Uri[] Endereco = new Uri[1] {new Uri("net.tcp://localhost:4141")};
               
                _Servidor = new ServiceHost(typeof(_Servico), Endereco);

                _Servidor.Description.Behaviors.Add(new ServiceMetadataBehavior());
                _Servidor.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
                _Servidor.AddServiceEndpoint(typeof(IContador), new NetTcpBinding(), "Contador");
                _Servidor.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
                _Servidor.Open();

            }
        }
    }

    Obrigado

    T+
    quinta-feira, 11 de março de 2010 20:10