64 Bits c/ GX .. solução ou só mais dor de cabeça ???
Autor: Ricardo Oliveira | Publicado: 2010-10-21T02:10:00-03:00

Tinhamos um código em GX 9 (.net WIN ) que funcionava muito bem no nosso cliente.. 

Vejam abaixo:

&amp;vrMailMessage.To.New( &amp;NomeSacado, &amp;EnderecoEmail )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&amp;vrMailMessage.From.Address = 'XYZ@ABC.ORG.BR'

&nbsp;&amp;vrMailMessage.From.Name = 'CLIENTE DE EMAIL' 
&nbsp;&amp;vrMailMessage.CC.New( 'NOME CLIENTE', 'email@cliente.com.br')&nbsp;&nbsp;
&amp;vrMailMessage.Subject = 'Envio de E-mail de Boleto do Depto'&nbsp;&nbsp;
&amp;vrMailMessage.HTMLText = &amp;BoletoHtml

&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 5000
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Host&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = CON_PARAMETROS.PAR_HOST_EMAIL
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Sender.Name&nbsp;&nbsp;&nbsp;&nbsp; = 'Depto'
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Sender.Address&nbsp; = ' XYZ@ABC.ORG.BR’&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Authentication&nbsp; = 1&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.UserName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp; CON_PARAMETROS.PAR_USER_EMAIL
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Password&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp; CON_PARAMETROS.PAR_USER_PASSWORD_EMAIL
&nbsp;&nbsp;&nbsp; Msg('Aguardando logon do servidor : SMTP.HOST.COM.BR , aguarde...Timeout(' + &amp;vrSMTP.Timeout.ToString() + ')' , status)
&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Login()&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; If &amp;vrSMTP.ErrCode = 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;vrSMTP.Send(&amp;vrMailMessage)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If &amp;vrSMTP.ErrCode = 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msg('Email enviando para: ' + &amp;EnderecoEmail + ' com sucesso!')
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msg(&amp;vrSMTP.ErrDescription)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Endif
&nbsp;&nbsp;&nbsp; Else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msg(&amp;vrSMTP.ErrDescription)
&nbsp;&nbsp;&nbsp; Endif
&nbsp;&nbsp; &amp;vrSMTP.Logout()

Funcionava muito bem.. até a uns 15 dias atrás.. que o cliente (usuário) começou a NOS pressionar reclamando de travamento na máquina. Fiz o teste em OUTRAS máquinas OK, tudo funcionando muito bem até que descobrimos que num belo dia trocaram a máquina do cliente para um 64 BITS e não nos avisaram.

Adivinhem o que aconteceu ???

O envio de email começou a travar somente nesta máquina 64 bits.. apesar de estar com o WIN XP 32.. Desativamos o firewall, desativamos o anti-virus. Mas travar o que ??. devem estar curiosos .. 

Durante o envio do e-mail&nbsp; via datatype SMTPsession.. é que estava travando , mesmo configurando o timeout&nbsp; na propriedade do SMTPSession?? pau do Timeout só&nbsp; a Artech e o suporte deverá me responder.

E ai .. o que responder ao cliente.. procura daqui , reza dali, consulta os universitários, GOOGLE do desespero, até que achamos algo parecido no WEB SAC da artech.

csharp try
csharp {
csharp string SMTPUserName = [!&amp;NomeSacado!];
csharp string EMailTo = [!&amp;EnderecoEmail!];
csharp string EMailSubject = "Envio de E-mail de Boleto do Depto ";
csharp string EMailMessage = [!&amp;BoletoHtml!];
csharp string SMTPHost = "host.smtp.com.br";
csharp int SMTPPort = 25;
csharp string SMTPEmailPassword = "senha";
csharp System.Net.Mail.MailMessage mM = new System.Net.Mail.MailMessage();
csharp mM.From = new System.Net.Mail.MailAddress("email@envio.com.br");
csharp mM.To.Add(EMailTo);
csharp mM.Subject = EMailSubject;
csharp mM.Body = EMailMessage;
csharp mM.IsBodyHtml = true;
csharp mM.Priority = System.Net.Mail.MailPriority.High;
csharp System.Net.Mail.SmtpClient sC = new System.Net.Mail.SmtpClient(SMTPHost, SMTPPort);
csharp sC.EnableSsl = false;
csharp sC.Timeout = 5000;
csharp string strId;
csharp string strPassword;
csharp strId = "email@envio.com.br"; 
csharp strPassword = SMTPEmailPassword;
csharp sC.UseDefaultCredentials = false;
csharp sC.Credentials = new System.Net.NetworkCredential(strId, strPassword);
csharp sC.Send(mM);
csharp [!&amp;statusEnvio!] = 1;
csharp }
csharp catch (System.Exception ex)
csharp {
csharp [!&amp;statusEnvio!] = 0;
csharp [!&amp;ErroDescricao!] = ex.Message;
csharp }

&nbsp;&nbsp;&nbsp; If &amp;statusEnvio = 1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msg('Mensagem enviada c/ sucesso pelo servidor smtp.host.com.br : (' + &amp;statusEnvio.ToString() + ')')
&nbsp;&nbsp;&nbsp; Else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msg('Mensagem não enviada p/ servidor smtp.host.com.br : (' + &amp;statusEnvio.ToString() + ')')
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msg(&amp;ErroDescricao.Trim())
&nbsp;&nbsp;&nbsp; Endif

Bingo . funcionou .. corretamente, dor de cabeça, c/os “;” no final das tags do csharp, entender o que cada&nbsp; instrução faz e como interage no GX.

Este problema/solução está reportado&nbsp; no SAC 28.830 , e será consertado somente no GX EVL UPGRADE 4.

Restou a nós uma conclusão ou exagero, PAU no Timeout(motivo do travamento) dos comandos(smtpSession) do GX ??? ou Pau nos comandos do GX 64 BITS ??&nbsp; pois este problema não aconteceu nas outras máquinas (WIN XP 32 BITS, e WIN 2003) ???

Até quando vamos precisar apelar a linguagem(nativa) para resolvermos nosso problemas urgentíssimos ???

E os mesmos problemas recentes do GX&nbsp; 9.0 em 64 bits se repetirão no GX X EVL 1 ou EVL 2 ??? E na hora de utilizarmos linguagens mais recentes ??? Ruby apelaremos para quem ??&nbsp; o Santo Darma Ruby ?? existe ?? no Japão ???

E oura coisa.. o código csharp gerado manualmente pelas tags CSHARP estão impossíveis de serem entendidos .. vejam abaixo:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.CidadeSacado = AV54Cidade.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.EstadoSacado = AV24Estado.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.CepSacado = AV25CepSac.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AV6Hoje = DateTimeUtil.DToC( DateTimeUtil.Today( ), 4, "/") ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.DataDocumento = AV6Hoje;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AV7Vencime = DateTimeUtil.DToC( AV30Vencim, 4, "/") ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.DataVencimento = AV7Vencime.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.NumeroDocumento = AV26Numero.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.ValorDocumento = (double)AV27ValorD;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PercentualJurosDiaAtraso = (double)AV32Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PercentualMultaAtraso = (double)AV33Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PercentualDesconto = (double)AV34Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.DiasProtesto = AV35Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PadroesBoleto.Demonstrativo = AV28Demons.Trim();

O código acima não ficaria mais fácil de entender se fosse conforme o código abaixo??( tudo bem que o código abaixo é em GX 9, talvez em GX X/EVL esteja melhor)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.CidadeSacado = AV54Cidade.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.EstadoSacado = AV24Estado.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.CepSacado = AV25CepSac.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AV6Hoje = DateTimeUtil.DToC( DateTimeUtil.Today( ), 4, "/") ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.DataDocumento = AV6Hoje;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AV7Vencime = DateTimeUtil.DToC( AV30Vencim, 4, "/") ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.DataVencimento = AV7Vencime.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.NumeroDocumento = AV26Numero.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.ValorDocumento = (double)AV27ValorD;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PercentualJurosDiaAtraso = (double)AV32Empres;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Boleto.PercentualMultaAtraso = (double)AV33Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PercentualDesconto = (double)AV34Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.DiasProtesto = AV35Empres;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boleto.PadroesBoleto.Demonstrativo = AV28Demons.Trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* User Code */

Ou .. se&nbsp; o código abaixo 

csharp string EMailSubject = "Envio de E-mail do Depto ";
csharp string EMailMessage = [!&amp;BoletoHtml!];
csharp string SMTPHost = "host.de.envio";
csharp int SMTPPort = 25;
csharp string SMTPEmailPassword = "senha";

não poderia ser escrito assim e GX ?

CSHARP{
string EMailSubject = "Envio de E-mail do Depto ";
string EMailMessage = [!&amp;BoletoHtml!];
string SMTPHost = "host.de.envio";
int SMTPPort = 25;
string SMTPEmailPassword = "senha";


Vai aqui nossa modesta experiência em geradores:
Gerar código comentando linha a linha ajuda e muito a manutenção / debug por parte dos desenvolvedores; 
E o&nbsp; principal;&nbsp; a geração(sobreposição) de código nativo(feito pelo programador) sobre o código gerado pelo GX deveria ser respeitado e de responsabilidade do analista/desenvolvedor a qualquer momento e em qualquer situação.

Querem ver um exemplo clásico .. os códigos fontes gerados pelas principais classes do GX GXCommon, GXMail, GXDbi32, GXOffice, e pelo GXGeral .js deveriam estar de fácil acesso a equipe de desenvolvimento&nbsp; para que pudéssemos debugá-los e até alterá-los ao nosso gosto.

Claro , a Artech vai nos dizer que ai a responsabilidade de suporte dela terminaria até&nbsp; alterarmos o código fonte gerado, mas&nbsp; ai .. vamos responder .. aguardaríamos uma solução /debug até quando ?? a cada preview de 2 a dois meses ? até perdermos nosso contrato ??? por demora nesta solução por parte da Artech ??? 

Nós da área de TI, entendemos probleminhas, problemas e problemões..agora nossos clientes de diversas áreas não entendem e não gostam de esperar.

O post acima foi só para&nbsp; clarear a todos (nós, Artech , suporte e desenvolvedores) a que ponto chegamos na hora dos gargalos sérios.. e como podemos resolvê-los. O GX nos permite resolver vários problemas sérios de muitas maneiras.. (partir para&nbsp; a linguagem nativa é um deles.. ), mas o ideal é que&nbsp; não precisássemos disto.. mas se a pressão for grande não nos restará outro caminho.

Tunning de máquina, Tunning de banco de dados , Tunning de regras de negócios .. porque não Tunning de código gerado ???&nbsp; 

Somos leigos a que nível a lógica gerada(pelo GX) pode variar .. mas somos objetivos no que precisa ser revolvido... contem conosco .. nossa ajuda .. , nossas orações.. só espero nos ajudarem na hora do prejuízo e na corda do pescoço por parte do cliente.

Boa sorte a Artech , ao EVL2 e aos geradores móveis.

Abraço


Ricardo
RCO Proc. De Dados