Pregunta

Soy nuevo en las discusiones y en necesidad de ayuda. Tengo una aplicación de entrada de datos que tiene una cantidad exorbitante de tiempo para insertar un nuevo registro (es decir 50-75 segundos). Así que mi solución fue enviar una instrucción de inserción a cabo a través de un ThreadPool y permitir al usuario para comenzar a introducir los datos para el registro, mientras que el inserto que devuelve un nuevo identificador de registro, mientras que la inserción está en marcha. Mi problema es que un usuario puede golpear en Guardar antes de la nueva ID se volvió de esa inserción.

He intentado poner en una variable booleana que consiguen el valor true a través de un evento de ese hilo cuando sea seguro para guardar. Entonces puse en

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

Creo que es una mala idea. Si funciono con el método de guardar antes de que la rentabilidad de la banda de rodadura, se queda atascado.

Así que mis preguntas son:

  1. ¿Hay una mejor manera de hacer esto?
  2. ¿Qué estoy haciendo mal aquí?

Gracias por cualquier ayuda.
Doug

Editar para más información:

Se está haciendo una inserción en una (tamaño máximo acercándose) muy grande base de datos de FoxPro. El archivo tiene unos 200 campos y casi tantos índices en ella.
Y antes de preguntar, no No puedo cambiar la estructura de la misma, ya que estaba aquí antes de que yo y hay un montón de código heredado golpeándola. El primer problema es que, con el fin de conseguir un nuevo ID primero debo encontrar el max (id) en la tabla a continuación, incrementar y suma de comprobación ella. Para eso se necesita unos 45 segundos. A continuación, la primera inserción es simple y de inserción de esa nueva identificación y un campo enterdate. Esta tabla no es / no se puede poner en un DBC para que descarta las identificaciones y la generación de auto-similares.

@ joshua.ewer
Usted tiene la proccess correcta y creo que para el corto plazo simplemente voy a desactivar el botón de guardar, pero se le busca en su idea de pasarlo en una cola. ¿Tiene alguna mención de MSMQ que debería echar un vistazo a?

¿Fue útil?

Solución

Todos los demás, incluyendo a usted, se dirigió a los problemas de fondo (tiempo de inserción, por qué estás haciendo una inserción, a continuación, actualizar), así que me quedo con sólo los problemas técnicos con la solución propuesta. Así que, si me da el derecho de flujo:

  • Rosca 1: Iniciar la entrada de datos para el registro

  • Tema 2: Antecedentes llama a la base de datos para recuperar los nuevos ID

  • El botón de guardar siempre está habilitada, si el usuario intenta guardar antes de rosca 2 completa, que ponen # 1 para dormir durante 200 ms?

El más simple, no es el mejor, la respuesta es simplemente haya desactivado el botón, y tienen que hacer un hilo devolución de llamada a un delegado que habilita el botón. No pueden iniciar la operación de actualización hasta que esté seguro que las cosas están configurados apropiadamente.

Sin embargo, creo que una solución mucho mejor (aunque podría ser exagerado si sólo la construcción de un Q & D frontal a FoxPro), sería la de poner a estos guardar las operaciones en una cola. El usuario puede teclear lo más rápidamente posible, a continuación, las peticiones se ponen en algo así como MSMQ y se puede completar en su propio tiempo de forma asíncrona.

Otros consejos

1) Muchos :), por ejemplo, usted podría desactivar el botón "Guardar", mientras que el hilo es insertar el objeto, o puede configurar un subproceso de trabajo que manejan una cola de "salvar las solicitudes" (pero creo que el problema aquí es que el usuario desea modificar el registro recién creado, así que deshabilitar el botón tal vez es mejor)

2) Creo que necesitamos algo más de código para ser capaz de entender ... (o tal vez es un problema de sincronización, no soy un fan de errores de hilos también)

por cierto, sólo que no entiendo por qué una inserción debe tener por lo long..I pensar que usted debe comprobar que el código primero! <- al igual que Charles se dijo antes (lo siento, DIND'T leer el post):)

Utilizar un futuro en lugar de una acción ThreadPool prima. Ejecutar el futuro, permite al usuario hacer lo que quieran, cuando llegan a Guardar en la segunda grabación, solicitar el valor del futuro. Si la primera inserción ya terminado, que obtendrá el ID de inmediato y se le permitirá el segundo inserto para dar comienzo. Si aún están a la espera de la primera operación, el futuro se bloqueará hasta que esté disponible, y luego la segunda operación se puede ejecutar.

No está ahorrando cualquier momento a menos que el usuario es más lenta que la operación.

En primer lugar, probablemente debería saber, y fijar, la razón por la cual un inserto está tomando tanto tiempo ... 50-75 segundos es razonable que cualquier base de datos moderna para una sola fila de inserción, e indica que algo más tiene que ser dirigida, como índices, o el bloqueo de ...

En segundo lugar, ¿por qué estás insertando el registro antes de tener los datos? Normalmente, las aplicaciones de entrada de datos se codifican de manera que el inserto no se intenta hasta que todos los datos necesarios para la inserción ha sido recopilada del usuario. ¿Estás haciendo esto porque usted está tratando de obtener el nuevo Id de vuelta de la primera base de datos, y luego "actualizar" el nuevo registro vacío con los datos introducidos por el usuario posteriores? Si es así, casi todos los vendedores de la base de datos tiene un mecanismo donde se puede hacer la inserción de una sola vez, sin conocer el nuevo ID, y tienen la base de datos devuelve la nueva identificación, así ... ¿Qué base de datos del proveedor está usando?

es una solución como esto sea posible:

Pre-calcular los identificadores únicos para que un usuario comience a agregar. Mantenga una lista de los ID únicos que ya están en la mesa, pero son efectivamente marcadores de posición. Cuando un usuario está tratando de insertar, reservarlos uno de los identificadores únicos, cuando el usuario presiona ahorrar, que ahora reemplazan el lugar titular con sus datos.

PS: Es difícil confirmar esto, pero ser consciente del problema siguiente concurrencia con lo que usted propone (con o sin hilos): El usuario A, empieza a sumar, el usuario B empieza a sumar, el usuario A calcula ID 1234 como la libre ID max, el usuario B calcula ID 1234 como la libre ID max. Un usuario inserta ID 1234, ID de usuario inserta B = 1234 Boom!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top