Pergunta

Eu sou novo para tópicos e precisa de ajuda. Eu tenho um aplicativo de entrada de dados que leva uma quantia exorbitante de tempo para inserir um novo registro (ou seja 50-75 segundos). Assim, a minha solução foi enviar uma instrução de inserção para fora através de um ThreadPool e permitir que o utilizador para começar a introduzir os dados para o registro enquanto que inserção que retorna um novo ID de registro, enquanto que inserir está em execução. Meu problema é que um usuário pode clicar em salvar antes que o novo ID é retornado de que inserção.

Eu tentei colocar em uma variável booleana que prepare-se para a verdadeira via um evento desse segmento quando é seguro para salvar. Eu, então, colocar em

while (safeToSave == false)  
{  
    Thread.Sleep(200)  
}  

Eu acho que é uma má idéia. Se eu executar o método de salvar antes que piso retorna, ele fica preso.

Então, minhas perguntas são:

  1. Existe uma maneira melhor de fazer isso?
  2. O que estou fazendo de errado aqui?

Obrigado por qualquer ajuda.
Doug

Editar para mais informações:

Ele está fazendo uma inserção em um (tamanho máximo aproximando) muito grande banco de dados FoxPro. O arquivo tem cerca de 200 campos e quase tão muitos índices sobre ele.
E antes que você pergunte, não, eu não posso mudar a estrutura de como ele estava aqui antes de eu era e há uma tonelada de código legado bater. O primeiro problema é que, a fim de obter um novo ID devo primeiro encontrar o max (id) na tabela, em seguida, incrementar e soma de verificação-lo. Isso leva cerca de 45 segundos. Em seguida, a primeira inserção é simples e inserção desse novo ID e um campo enterdate. Esta tabela não é / não pode ser colocado em um DBC para que exclui ids auto-geração e similares.

@ joshua.ewer
Você tem a proccess correta e eu acho que para o curto prazo vou apenas desabilitar o botão salvar, mas eu vou estar olhando para a sua ideia de passá-lo em uma fila. Você tem referências a MSMQ que eu deveria dar uma olhada?

Foi útil?

Solução

Todos os outros, incluindo você, abordou os problemas centrais (insert tempo, porque você está fazendo uma inserção, em seguida, atualização), então eu vou ficar apenas com as preocupações técnicas com a solução proposta. Então, se eu conseguir o direito de fluxo:

  • Thread 1: entrada de dados inicial para registro

  • Thread 2: chamadas Fundo para DB para recuperar novo Id

  • O botão Salvar é sempre ativado, se o usuário tenta salvar antes Tópico 2 tiver sido concluído, você coloca # 1 para dormir por 200 ms?

O mais simples, não melhor, a resposta é apenas ter o botão desativada, e ter esse segmento fazer uma callback a um delegado que permite que o botão. Eles não podem iniciar a operação de atualização até que você esteja se as coisas estão configurados adequadamente.

Embora, eu acho que uma solução muito melhor (embora possa ser exagerada, se você está construindo apenas um Q & D front-end para FoxPro), seria a de lançar as operações de gravação em uma fila. O usuário pode digitar o mais rápido possível, em seguida, os pedidos são colocados em algo como MSMQ e eles podem completar em seu próprio tempo de forma assíncrona.

Outras dicas

1) Muitos :), por exemplo, você poderia desativar o botão "Salvar", enquanto o segmento está inserindo o objeto, ou você pode configurar um segmento de trabalho que lidar com uma fila de "save solicitações" (mas eu acho que o problema aqui é que o usuário deseja modificar o registro recém-criado, de modo a desabilitação do botão talvez seja melhor)

2) Eu acho que precisamos de mais algum código para ser capaz de entender ... (ou talvez é um problema de sincronização, eu não sou um fã bug de tópicos também)

btw, eu só não entendo por que uma inserção deve levar tanto long..I pensar que você deve verificar que o código em primeiro lugar! <- assim como charles dito antes (desculpe, dind't ler o post):)

Use a futuro ao invés de uma ação ThreadPool cru. Executar o futuro, permitir que o usuário fazer o que quiserem, quando batem Guardar no 2º registro, solicitar o valor do futuro. Se o primeiro inserção já terminado, você terá a ID imediatamente e a 2ª inserção será permitida a pontapé de saída. Se você ainda está esperando no 1º operação, o futuro irá bloquear até que esteja disponível, e então a segunda operação pode executar.

Você não está salvando qualquer momento, a menos que o usuário é mais lento que a operação.

Em primeiro lugar, você provavelmente deve descobrir, e correção, a razão pela qual uma inserção está demorando tanto ... 50-75 segundos é razoável para qualquer banco de dados moderno para uma única inserção de linha, e indica que algo precisa mais havendo a ser abordada, como índices, ou bloqueando ...

Em segundo lugar, por que você está inserindo o registro antes que você tenha os dados? Normalmente, as aplicações de entrada de dados são codificados de modo a que o inserto não é tentado até que todos os dados necessários para a inserção foi recolhida a partir do utilizador. Você está fazendo isso porque você está tentando obter a nova volta Id do banco de dados primeiro, e depois "update" o novo registro vazia com os dados introduzidos pelo utilizador posteriores? Se assim for, quase todos os fornecedores de banco de dados tem um mecanismo onde você pode fazer a inserção de uma única vez, sem conhecer o novo ID, e ter o banco de dados retornar o novo ID, bem ... O banco de dados do fornecedor que você está usando?

É uma solução como esta possível:

Pré-calcular os IDs exclusivos antes que um usuário começa mesmo a acrescentar. Mantenha uma lista de de identificação única que já estão na tabela, mas são efetivamente titulares lugar. Quando um usuário está tentando inserir, reserva-os uma das identificações exclusivas, quando o usuário pressiona salvar, eles agora substituir lugar o porta-com os seus dados.

PS: É difícil confirmar isso, mas estar ciente do seguinte problema de concorrência com o que você está propondo (com ou sem fios): O usuário A, começa a adicionar, começa usuário B para adicionar, o usuário calcula um ID 1234 como o ID livre max, o usuário B calcula ID 1234 como o ID livre máx. inserções Usuário A ID 1234, usuário insere B ID 1234 = Crescimento!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top