[dotnetarchitects] Compatilhar Memória entre dois Aplicativos distintos

58 views
Skip to first unread message

Bruno Fernandes

unread,
Mar 1, 2013, 2:45:23 PM3/1/13
to Dot Net Architects
PessoALL, boa tarde!

Confesso, que a minha pesquisa no Google foi superficial... Nem sei se o que eu quero, tem um nome de tecnologia ou padrão de projeto pra isso.

O que preciso é basicamente ter um espaço de memória que seja compartilhado, em princípio, por dois aplicativos distintos no mesmo PC.
Este espaço de memória vai armazenar basicamente uma lista de objetos com dois atributos (Int64 e dateTime).

Um aplicativo "A" vai incluir um objeto na lista ao acaso, e o Aplicativo "B" (no mesmo computador) deve ler (e remover) estes objetos constantemente (eventualmente incluir um novo).

Sei que poderia implementar essa funcionalidade através de arquivo (texto ou xml), mas o IO de HD ficaria extremamente alto...
Gostaria de saber se há uma forma melhor de fazer isso sem envolver arquivo ou mensagens via "Socket".

Em princípio eu imaginei compartilhar a própria RAM (não sei como) por questões de velocidade no processamento.
Sabem me dizer se há alguma classe .Net que me permita tal proeza? Que outra arquitetura sugerem?

Att. 


Renato Cantarino

unread,
Mar 1, 2013, 2:47:20 PM3/1/13
to dotnetar...@googlegroups.com
caraca...
sexta ta tensa....


--
Você recebeu esta mensagem porque faz parte do grupo .Net Architects hospedado no Google Groups.
Para postar envie uma mensagem para dotnetar...@googlegroups.com
Para sair do grupo envie uma mensagem para dotnetarchitec...@googlegroups.com
Para mais opções visite o grupo em http://groups.google.com/group/dotnetarchitects?hl=pt-br
---
Você está recebendo esta mensagem porque se inscreveu no grupo ".Net Architects" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para dotnetarchitec...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--

Att,
Renato Cantarino

Bruno Fernandes

unread,
Mar 1, 2013, 2:50:44 PM3/1/13
to dotnetar...@googlegroups.com
kkk... Está??? Eu estou bem relax!!!
Cuidado pra não infartar, hein @Cantarino?!?

Att. 
Bruno Fernandes

Pedro Nicholas Souza Alves

unread,
Mar 1, 2013, 2:57:05 PM3/1/13
to dotnetar...@googlegroups.com
Cara, redis.io. Banco de dados NoSQL em Memória.
Pedro Souza

55+ (11) 9-9915-9977

Winston Pacheco Junior

unread,
Mar 1, 2013, 2:58:07 PM3/1/13
to dotnetar...@googlegroups.com
Velho, quem sabe não é o momento da reativação do Bamboo.Prevalence!
Me parece um bom case!

Chama Inter Process Communication:

Acredito que Shared Memory não possa ser feito em .net diretamente... Aliás, olhando o google vi que é possível usando .net 4

Porque antes só através de código não gerenciado.
Tome cuidado se for utilizar o último caso, problemas malucos aconteciam quando eu era estudante e programava em C++ por falta de prática no uso de memória diretamente.

Em 1 de março de 2013 16:45, Bruno Fernandes <bruno...@gmail.com> escreveu:

--

Gustavo Cruz

unread,
Mar 1, 2013, 2:59:24 PM3/1/13
to dotnetar...@googlegroups.com
Cara, o seu volume de IO vai ser tão alto assim pra precisar trabalhar direto na memória?! Porque chega uns malucos aqui falando que precisam de performance absurda, e quando vai ver o volume não passa de 1k....



2013/3/1 Bruno Fernandes <bruno...@gmail.com>

Renato Cantarino

unread,
Mar 1, 2013, 3:02:02 PM3/1/13
to dotnetar...@googlegroups.com
Acho que ate um Xml atende...
O aplicativo B, ficará todo segundo verificando a lista A?

Renato Cantarino

unread,
Mar 1, 2013, 3:03:37 PM3/1/13
to dotnetar...@googlegroups.com
Thread A : consulta e monta a lista.
Thread B : consulta A, processa de tempos em tempos.

--

Att,
Renato Cantarino

André Körbes

unread,
Mar 1, 2013, 3:12:08 PM3/1/13
to dotnetar...@googlegroups.com
Cara, isso chama IPC e pode dar mais problemas que vc imagina.

Se vc explicar melhor seu cenário (dois processos criados por vc, tudo em .net, como vai funcionar essa leitura/escrita, necessidade de performance, etc e tal) acho que o pessoal pode te ajudar mais.

Sobre fazer Shared Memory em .Net, dá pra fazer usando P/Invoke e funciona bem.

André

Bruno Fernandes

unread,
Mar 1, 2013, 3:28:47 PM3/1/13
to dotnetar...@googlegroups.com
@Cantarino,
Não é todo o segundo, mas é de 10 em 10 segundos no MÁXIMO.
(ACHO que) Não dá pra fazer com simples Threads...

@ALL
Mundo real:
Tenho um sistema de agendamento de SMSs e alguns são agendados para ser enviado na hora/minuto/segundo marcado.
Outros precisam ser enviados imediatamente, assim que a mensagem chega no servidor de banco de dados (num servidor hospedado em um host remoto)

Como funciona hoje: Tenho um Serviço Windows que a todo momento (a cada 4 segundos para ser mais preciso), eu faz uma consulta no meu SQLServer(também no host remoto) perguntando se tem alguma mensagem pendente de envio... se tiver, ele envia e registra o envio no banco. 4 segundos depois disso, repete-se o processo, pois uma nova mensagem pode chegar a qualquer momento com envio imediato. Isso funciona bem, mas o trafego de dados na minha rede e internet é muito grande... sem contar o processamento de queries no SQLServer à cada 4 segundos.

Minha ideia: Ao invés de ficar perguntando à cada 4 segundos pro servidor se tem alguma coisa nova pra mim, gostaria de ser avisado quando chegar alguma coisa nova. Então, eu teria uma lista (em memória) dos Id's e Agendamentos das mensagens programadas para envio.
Quando o servidor (hospedado em um host remoto) receber uma mensagem nova, ele grava no banco e atualiza essa lista através de um WebService (Aplicativo "A") no meu PC (onde tenho um hardware específico pra isso instalado).

Em paralelo à isso, o Serviço Windows (Aplicativo "B") também no meu PC, continua funcionando de forma similar, mas ao invés de perguntar pro servidor remoto, pergunta pra lista compartilhada em memória.

Bem, é isso!

Att. 


Bruno Fernandes

unread,
Mar 1, 2013, 3:48:35 PM3/1/13
to dotnetar...@googlegroups.com
@Pedro Nicholas, @Winston, @André Korbes
Valeu pelos links e pelas dicas, vou dar uma olhada e procurar mais à Respeito

@Gustavo Cruz
Eu não preciso de uma performance absurda, só preciso que um SMS "agendado" pra agora não demore mais que 15 segundos para chegar ao destinatário.
Imagine um cadastro de um site que ao invés de utilizar "capcha", utilize o meu serviço de envio de SMS...
Imagine que alguém se cadastre e para confirmar o cadastro ele precise digitar o código de acesso "enviado" para o celular dele...
Eu ficaria muito "fulo" da vida se o SMS não chegasse em um intervalo de tempo "satisfatório" que pra mim, seria de até 15 segundos...
[OFF] Quanto aos "malucos por performance absurda"... eu sou um desses caras, hahaha! [/OFF]

Att. 


Saulo Brito

unread,
Mar 1, 2013, 4:05:22 PM3/1/13
to dotnetar...@googlegroups.com
Que bom que você é desses caras.

No site da operadora Claro costumo esperar no mínimo 2 min até 30 min por uma mensagem com senha em alguma operação de cadastro.


Abraços,
Saulo Brito

Hugo Estevam Longo

unread,
Mar 1, 2013, 4:06:39 PM3/1/13
to dotnetar...@googlegroups.com
@Fernandes,
 
Certa vez precisei fazer algo parecido.
 
Utilizei o framework Quartz.NET no projeto. Esse framework me auxiliou no controle de agendamento (envio e persistencia).
 
Na parte de persistencia ele tem uma abstração bem legal, você decide facilmente se deseja salvar em banco ou se quer que fique em memória através da interface IJobStore.
 
Para o meu cenário resolveu, recomendo que dê uma estudada, talvez sirva para você também...segue o link: http://quartznet.sourceforge.net/features.html
 
Um abraço
Hugo Estevam

Luciano Azevedo

unread,
Mar 1, 2013, 4:11:37 PM3/1/13
to dotnetar...@googlegroups.com
Com Mensageria vc resolve isso. 


Em 1 de março de 2013 17:48, Bruno Fernandes <bruno...@gmail.com> escreveu:



--
[ ]'s
Luciano Azevedo

André Körbes

unread,
Mar 1, 2013, 4:42:46 PM3/1/13
to dotnetar...@googlegroups.com
Bruno,

Tem algum motivo para vc fazer o WebService separado do Windows Service, e incluir essa memória compartilhada criando uma complexidade adicional? Porque não colocar os dois serviços no mesmo processo e ambos mexerem na lista como for necessário, já que vc teria que mexer no Windows Service de qualquer forma?

André

Gustavo Cruz

unread,
Mar 1, 2013, 5:02:47 PM3/1/13
to dotnetar...@googlegroups.com
@Bruno,

Eu particularmente não trabalharia em memória, nessa situação em específico. Um porque se o seu volume de dados aumentar demais, você na prática vai precisar de um servidor muito parrudo para segurar essa lista em memória. Sei não...eu partiria para uma solução de mensageria como o @Luciano sugeriu. Aqui na empresa tenho uma situação semelhante e funciona muito bem. 

Até um WCF + MSMQ dá conta. Ou se precisar de algo mais avançado, dá pra implementar um ServiceBus...(dá uma olhada no MassTransit e no NServiceBus).
E você não corre o risco de perder a lista no meio do caminho.... fora que fica com opções de sobra pra trabalhar com eventos de pub/sub...request/response etc.





2013/3/1 Luciano Azevedo <llo...@gmail.com>

Bruno Fernandes

unread,
Mar 1, 2013, 5:06:05 PM3/1/13
to dotnetar...@googlegroups.com
Então...

Estou justamente em busca dessa arquitetura de tentar simplificar as coisas... Eu ainda não implementei o WebService... foi uma idéia que tive, mas nem sei se é a melhor...

Tem um ponto importante esqueci de mencionar. O hardware que envia SMS não pode ser acessado simultaneamente por Threads diferentes (nesse caso, estou utilizando a porta serial para comunicação com o hardware, e se ela tiver aberta em uma Thread, a outra não consegue acessá-la)

Então, um dos motivos é: só posso ter um processo rodando que acesse a porta serial, nesse caso o Windows Service. Se eu tivesse utilizando o WebService, eu teria uma Thread para cada requisição no servidor, e certamente vai ocorrer de duas Threads serem iniciadas quase que simultaneamente, tentariam acessar a Serial ao mesmo tempo.

Pelo pouco conhecimento que tenho, acho que não seria bom ter um processo em "loop infinito" dentro do WebService no IIS verificando a lista de mensagens. E Por outro lado, não sei como fazer o meu Windows Service receber uma request de um servidor (assim como o WebService já o faz)

Att. 


Bruno Fernandes

unread,
Mar 1, 2013, 5:24:51 PM3/1/13
to dotnetar...@googlegroups.com
@Gustavo
Eu acredito que a minha lista não irá crescer muito não... a idéia e que a lista tenha somente os agendamentos das próximas 8 horas.
E a cada vez que eu for no servidor (host remoto) para gravar que o SMS foi enviado, eu pego os agendamentos nas próximas 8 horas e atualizo a lista com os novos horários, eliminando os que já passaram.

ACHO, somente ACHO, que a minha lista não vai ter mais que 1000 horários de envio para o intervalo de 8 horas. Mas mesmo que chegue à 10.000 em 8 horas, não acho que seja um grande volume de dados... (e se chegar à 20.000 envios à cada 8 horas, certamente eu paro de trabalhar, rsrs...)

De qualquer forma, vou dar uma olhada no WCF... Obrigado pelas dicas!

Att. 
Bruno Fernandes


Em 1 de março de 2013 19:20, Gustavo Cruz <gfcm...@gmail.com> escreveu:
Com WCF você faz isso....


Em 1 de março de 2013 19:02, Gustavo Cruz <gfcm...@gmail.com> escreveu:
@Bruno,

Eu particularmente não trabalharia em memória, nessa situação em específico. Um porque se o seu volume de dados aumentar demais, você na prática vai precisar de um servidor muito parrudo para segurar essa lista em memória. Sei não...eu partiria para uma solução de mensageria como o @Luciano sugeriu. Aqui na empresa tenho uma situação semelhante e funciona muito bem. 

Até um WCF + MSMQ dá conta. Ou se precisar de algo mais avançado, dá pra implementar um ServiceBus...(dá uma olhada no MassTransit e no NServiceBus).
E você não corre o risco de perder a lista no meio do caminho.... fora que fica com opções de sobra pra trabalhar com eventos de pub/sub...request/response etc.


2013/3/1 Bruno Fernandes <bruno...@gmail.com>

Gustavo Cruz

unread,
Mar 1, 2013, 5:20:01 PM3/1/13
to dotnetar...@googlegroups.com
Com WCF você faz isso....


2013/3/1 Bruno Fernandes <bruno...@gmail.com>

Eric Lemes

unread,
Mar 2, 2013, 9:29:35 AM3/2/13
to dotnetar...@googlegroups.com
Bruno,

O modo "roots" de se fazer isso é postar "windows messages" entre aplicações. Por baixo dos panos é o que qualquer framework faz. Dá um trabalho razoável, mas é a forma mais eficiente de se fazer. Também dá pra fazer por socket, filas, etc. Mas o jeito mais "low level" é esse. Acredito que o WCF abstraia isso pra você.

Em resumo, vc posta mensagens WM_COPYDATA na WindowProc da outra aplicação. Se você não tem a menor idéia do que eu estou falando, vale a pena estudar um pouquinho de API Win32. É como tudo no windows funciona.

Esse link dá uma idéia do que eu estou falando: http://www.codeproject.com/Articles/17606/NET-Interprocess-Communication


Abraço,

Eric


2013/3/1 Bruno Fernandes <bruno...@gmail.com>

--

Bruno Fernandes

unread,
Mar 2, 2013, 6:54:49 PM3/2/13
to dotnetar...@googlegroups.com
Grande Eric!

Obrigado pela dica... conheço alguma coisa da API Win32. Mas não sou expert!!!
Obrigado também pelo link... No exemplo, parece algo bem simples de implementar!

Atenciosamente,
Bruno Nogueira Fernandes

Eric Lemes

unread,
Mar 2, 2013, 7:57:18 PM3/2/13
to dotnetar...@googlegroups.com
Bruno,

É difícil algo em API Win32 que não seja dolorido de implementar... vc sempre vai mandar um ponteiro ou um teco de memória no lugar errado e vai se dar mal.

Mas se fizer direitinho, funciona sim. Se tiver doendo muito, dá uma olhadinha no PInvoke (para interoperabilidade .NET e DLL's C). Se tiver muito complicado, tem o easy-mode aqui:



Abraço,

Eric

2013/3/2 Bruno Fernandes <bruno...@gmail.com>

Leonardo Campos

unread,
Mar 5, 2013, 2:53:17 PM3/5/13
to dotnetar...@googlegroups.com
Mesmo chegando 04 dias atrasado na conversa e, como o pessoal desceu até o nível da Win32 API, vale à pena ler sobre Memory-Mapped File, que permite trabalhar com dados muito maiores do que o suportado pela RAM, persistidos ou não, sendo que neste último utiliza-se para memória compartilhada (IPC), e com leitura/escrita otimizadas pelo sistema operacional.

Porém, trabalho com sistema de envio de mensagem que, ao invés de salvar no banco de dados e DEPOIS verificar o que tem para ser enviado pelo Windows Service, nós enviamos a mensagem para o Windows Service e ele é responsável por salvar no banco e, ao mesmo tempo, "enfileira" um VO na memória (não usamos MSMQ) com os dados da mensagem. Há um gateway para cada operadora/broker com a sua fila de envio interna, onde, no seu caso, seria um gateway para a porta serial. Apenas se o sistema cair é que é feita uma consulta na base para buscar os SMSs pendentes e "enfileira" tudo novamente nos seus respectivos gateways, sempre ordenado pela data de envio, utilizando Monitor.Wait e Monitor.Pulse para controlar o tempo de envio da próxima mensagem ou a chegada de uma nova mensagem com data menor. Quanto ao volume, cabem milhares e milhares de VO's em memória e atende perfeitamente no cenário existente.

Não sei como é o seu sistema e quais alterações são possíveis de serem feitas, mas fica a ideia que eu achei simples e funcional.



2013/3/2 Eric Lemes <eric...@gmail.com>



--
Att.
Leonardo da Silva Campos

"Keep distance, coder coding!"

Bruno Fernandes

unread,
Mar 5, 2013, 9:25:56 PM3/5/13
to dotnetar...@googlegroups.com
@Eric,
Obrigado novamente pelos links... ajudaram bastante!

@Leonardo Campos,
Muito interessante a sua abordagem... o meu problema é que o meu projeto está bem no início... ainda não tenho muitos recursos financeiros para investir no projeto com um "colocation", ou com servidores + redes + link de internet dedicado + no breaks, etc...

Eu até poderia colocar toda a estrutura do serviço rodando aqui na "infra" que tenho em meu escritório, mas se faltar luz/internet, ninguém envia/Agenda SMSs...

Por isso, optei por colocar toda a logica de negócio e persistência, em um servidor remoto que me dá pelo menos 98% de uplink**, e eu aqui em meu escritório, ficam os hardwares necessários para o envio do SMS. Mesmo que falte luz/internet, os SMSs já estão registrados na base de dados remota, só tenho que consultar os que ainda não foram enviados para enviá-los.

**98% de uplink, eu sei, é pouco... mas se fosse tudo em meu escritório seria bem pior...

[merchan]
Link do Web Service: http://ws.mercadopleno.com.br
Aos interessados em parceria/integração, favor entrar em contato em PVT.
[/merchan]

Att. 
Bruno Fernandes

Daniel Porfirio

unread,
Mar 28, 2013, 3:58:48 PM3/28/13
to dotnetar...@googlegroups.com
Quando você diz:

"Ao invés de ficar perguntando à cada 4 segundos pro servidor se tem alguma coisa nova pra mim, gostaria de ser avisado quando chegar alguma coisa nova."

Isso não resolve o seu problema?



--
Att,

Daniel Porfirio

Bruno Fernandes

unread,
Mar 28, 2013, 7:45:02 PM3/28/13
to dotnetar...@googlegroups.com
@Porfirio
Interessante... não conhecia...

Vou fazer alguns testes e posto aqui os resultados...

Obrigado. 



--

edmilson hora

unread,
Mar 29, 2013, 6:42:59 AM3/29/13
to dotnetar...@googlegroups.com
Parece muito interessante, notificar a aplicação.
Gostaria muito de ver um modelo mesmo que bem siplificado de implementação.

Aguém ai se habilita a mostrar  como é que se usa?



De: Daniel Porfirio <m...@danielporfirio.com>
Para: dotnetar...@googlegroups.com
Enviadas: Quinta-feira, 28 de Março de 2013 16:58
Assunto: Re: [dotnetarchitects] Compatilhar Memória entre dois Aplicativos distintos

Daniel Porfirio

unread,
Mar 29, 2013, 8:56:13 AM3/29/13
to dotnetar...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages