Usuário com melhor resposta
Mensagem estranho de travamento...

Pergunta
-
Pessoal, tenho uma aplica;áo q precisa inserir no banco uns 1500 registros.
to tentando fazer esse processamento de inserir linha a linha num método com await:
await gravarNoBanco(registros);
ele começa a gravar, quando tá lá pela centésima linha aparece o seguinte erro:
O CLR não conseguiu fazer a transição do contexto COM 0x857f50 para o contexto COM 0x8580c0 em 60 segundos. O thread que possui o context/apartment de destino está provavelmente fazendo uma espera sem bombeamento ou processando uma operação de execução muito longa sem bombeamento das mensagens do Windows. Geralmente, essa situação tem um impacto negativo no desempenho e pode até mesmo levar à falta de resposta do aplicativo ou ao acúmulo contínuo de uso de memória com o tempo. Para evitar esse problema, todos os threads com um único apartment em thread (STA) devem usar primitivos de espera de bombeamento (como CoWaitForMultipleHandles) e bombear rotineiramente as mensagens durante operações de execução longa.
to usando sqlite com EF.
Alguém sabe me explicar o q tá havendo?
Outra coisa, embore eu use await, o processamento congela a janela do aplicativo enquanto ele está gravando os registros no banco.... como fazer pra evitar isso?
Se a resposta foi útil, por favor marque como útil. Leia a bíblia.
Respostas
-
Então Tiano,
é o seguinte, parece que para cada Anuncio tem 1 QS, certo?
Então, se no Modelo do banco o relacionamento foi feito de forma correta, a ferramenta que importa o modelo do EF deve ter criado uma propriedade do tipo QS para o seu anuncio.
using(myEntit db = new myEntit()){ Anuncio novoAnuncio = new Anuncio(); novoAnuncio.Id_Template = idTemplate; novoAnuncio.Texto = itemLinhasValidas; novoAnuncio.Data_Criacao = DateTime.Now.ToString(formatoData); novoAnuncio.Data_Ultima_Atualizacao = DateTime.Now.ToString(formatoData);
int qsLV = -1; if (itemLinhasValidas.Split('\t')[indexColunaQS] == "") qsLV = 0; else qsLV = Convert.ToInt32(itemLinhasValidas.Split('\t')[indexColunaQS]);
QS novoQS = new QS(); //novoQS.Id_Anuncio = novoAnuncio.Id_Anuncio; // Não necessário pois o EF atribui automaticamente novoQS.Valor_QS = qsLV; novoQS.Variacao = 0; novoAnuncio.QS = novoQS; db.Anuncio.Add(novoAnuncio); db.SaveChanges(); }
Tenta fazer o que eu coloquei acima!!!
Abraço!!
- Marcado como Resposta Tianodraco segunda-feira, 8 de abril de 2013 18:43
Todas as Respostas
-
Olá Tiano,
Há um tempo atras tive esse problema e a solução encontra-se neste link:
Abraço!
-
-
Fábio obrigado por sua resposta.
Veja o seguinte trecho de código
using(myEntities db = new myEntities()){ for(i = 0; i <= 1300; i++){ Anuncio novoAnuncio = new Anuncio(); novoAnuncio.Texto = "Este é o anúncio de número: " + i; db.Anuncio.Add(novoAnuncio); db.SaveChanges(); } }
Desculpe se tiver algum erro no código o fiz agora só pra ilustrar....
É desse jeito acima q eu to fazendo a inserção dos meus registros... mas pra inserir cerca de 1300 registro tá demorando quase 7 minutos!
Tem como eu empiulhar esses registros no EF e depois enviar em lote, salvando tudo de uma vez com um único SaveChanges?
Se a resposta foi útil, por favor marque como útil. Leia a bíblia.
-
Sim...
Retire o SaveChanges() do for!!!
using(myEntities db = new myEntities()) { for(i = 0; i <= 1300; i++){ Anuncio novoAnuncio = new Anuncio(); novoAnuncio.Texto = "Este é o anúncio de número: " + i; db.Anuncio.Add(novoAnuncio); } db.SaveChanges(); }
Abraço!!!
- Editado Fabio Alves Borges Rodrigues segunda-feira, 8 de abril de 2013 17:21
-
Fábio, desculpa minha ignorância, eu sem querer esqueci uma parte importante... vou por aqui o código completo pra vc ver:
using(myEntit db = new myEntit()){ Anuncio novoAnuncio = new Anuncio(); novoAnuncio.Id_Template = idTemplate; novoAnuncio.Texto = itemLinhasValidas; novoAnuncio.Data_Criacao = DateTime.Now.ToString(formatoData); novoAnuncio.Data_Ultima_Atualizacao = DateTime.Now.ToString(formatoData); db.Anuncio.Add(novoAnuncio); db.SaveChanges(); //GRAVA UM NOVO QS NO BANCO int qsLV = -1; if (itemLinhasValidas.Split('\t')[indexColunaQS] == "") qsLV = 0; else qsLV = Convert.ToInt32(itemLinhasValidas.Split('\t')[indexColunaQS]); QS novoQS = new QS(); novoQS.Id_Anuncio = novoAnuncio.Id_Anuncio; novoQS.Valor_QS = qsLV; novoQS.Variacao = 0; db.QS.Add(novoQS); db.SaveChanges(); }
Se eu tirar o savechanges do loop, a parte em novoQS.Id_Anuncio = novoAnuncio.Id_Anuncio; não fica prejudicada.... pq assim, como o EF sabe qual é o id_Anuncio no banco se o registro não foi gravado no banco (q tem um campo autoincrement nesse campo)?
Eu tentei aqui de todo jeito e dá erro:
Não é possível determinar a extremidade principal da relação 'smcdbModel.FK_QS_0_0'. Várias entidades adicionadas podem ter a mesma chave primária.
A tabela QS possui uma foreign key para a chave primária da tabela Anuncio
Quando gravo um anuncio, preciso tb depois gravar valores na tabela QS...
Se a resposta foi útil, por favor marque como útil. Leia a bíblia.
- Editado Tianodraco segunda-feira, 8 de abril de 2013 17:46
-
Então Tiano,
é o seguinte, parece que para cada Anuncio tem 1 QS, certo?
Então, se no Modelo do banco o relacionamento foi feito de forma correta, a ferramenta que importa o modelo do EF deve ter criado uma propriedade do tipo QS para o seu anuncio.
using(myEntit db = new myEntit()){ Anuncio novoAnuncio = new Anuncio(); novoAnuncio.Id_Template = idTemplate; novoAnuncio.Texto = itemLinhasValidas; novoAnuncio.Data_Criacao = DateTime.Now.ToString(formatoData); novoAnuncio.Data_Ultima_Atualizacao = DateTime.Now.ToString(formatoData);
int qsLV = -1; if (itemLinhasValidas.Split('\t')[indexColunaQS] == "") qsLV = 0; else qsLV = Convert.ToInt32(itemLinhasValidas.Split('\t')[indexColunaQS]);
QS novoQS = new QS(); //novoQS.Id_Anuncio = novoAnuncio.Id_Anuncio; // Não necessário pois o EF atribui automaticamente novoQS.Valor_QS = qsLV; novoQS.Variacao = 0; novoAnuncio.QS = novoQS; db.Anuncio.Add(novoAnuncio); db.SaveChanges(); }
Tenta fazer o que eu coloquei acima!!!
Abraço!!
- Marcado como Resposta Tianodraco segunda-feira, 8 de abril de 2013 18:43
-
Conceitualmente falando,
Quanto estamos utilizado o EF, primeiro preenchemos todo o nosso objeto sem se preocupar com os IDs que serão gerados... e depois adicionamos o Objeto ao EntitySet relacionado a este objeto... e depois efetuamos o SaveChanges();
Por exemplo... Imagine que tenho uma tabela Pedido e outra ItemPedido com relacionamento 1..n.
Passo 1:
Criar uma entidade Pedido (chamada de entPedido por exemplo) e preencher com dados do Pedido...Passo 2:
Para cada Item do Pedido, criar uma entidade ItemPedido, preenchê-la, e adicionar a coleção entPedido.ItemPedidos...Repare que ainda não obtivemos nenhum ID do banco...
Quando você executar o db.SaveChanges() os IDs serão criados e preenchidos de acordo com o relacionamento existente no banco.
Ou seja, não precisa de um SaveChanges() para o Pedido e outro SaveChanges para o ItemPedido...
Entendeu?
Abraço!!!
-
Fábio, 100% funcional!
Eis o código funcionando corretamente:
Anuncio novoAnuncio = new Anuncio(); novoAnuncio.Id_Template = idTemplate; novoAnuncio.Texto = itemLinhasValidas; novoAnuncio.Data_Criacao = DateTime.Now.ToString(formatoData); novoAnuncio.Data_Ultima_Atualizacao = DateTime.Now.ToString(formatoData); db.Anuncio.Add(novoAnuncio); //GRAVA UM NOVO QS NO BANCO int qsLV = -1; if (itemLinhasValidas.Split('\t')[indexColunaQS] == "") qsLV = 0; else qsLV = Convert.ToInt32(itemLinhasValidas.Split('\t')[indexColunaQS]); QS novoQS = new QS(); novoQS.Anuncio = novoAnuncio; novoQS.Valor_QS = qsLV; novoQS.Variacao = 0; db.QS.Add(novoQS);
Muito obrigado. Agora só falta esse processamento não travar a tela do aplicativo... to querendo colocar uma progressbar na tela, pq q a cada iteracao do loop ele va incrementando....
Vou marcar seus posts como resposta, tem como continuarmos nesse post depois q eu fizer isso?
Se a resposta foi útil, por favor marque como útil. Leia a bíblia.
-
Que bom...
Sem problemas... Assim que tiver dúvidas ou problemas... pode postar aqui, ou abrir novos posts para outro tipo de problemas...
de qualquer forma... sempre estou ligado aqui no forum!!!
E... não esqueça de marcar meus replies como resposta blz?
Abraço!!!
- Editado Fabio Alves Borges Rodrigues segunda-feira, 8 de abril de 2013 18:41