Usuário com melhor resposta
Tipo de instancia, concorrencia e deadlock

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?
Respostas
-
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
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 -
-
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 -
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();
}
-
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 -
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.
-
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 -
-
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 -
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;
}
-
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 -
-
-
-
-
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
-
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+