Domanda

Sono nuovo di discussioni e ha bisogno di aiuto. Ho una voce di applicazione di dati che richiede una quantità esorbitante di tempo per inserire un nuovo record (cioè 50-75 secondi). Così la mia soluzione era quella di inviare una dichiarazione di inserimento tramite un ThreadPool e consentire all'utente di iniziare a inserire i dati per il record mentre quella inserto che restituisce un nuovo ID record mentre quella inserto è in esecuzione. Il mio problema è che un utente può colpire Salva prima che il nuovo ID viene restituito da quella di inserimento.

Ho provato a mettere in una variabile booleana che vengono impostata su true tramite un evento da quel filo quando è sicuro di risparmiare. Ho poi messo in

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

Credo che sia una cattiva idea. Se faccio funzionare il metodo di salvare prima che restituisce battistrada, si blocca.

Quindi le mie domande sono le seguenti:

  1. C'è un modo migliore di fare questo?
  2. Che cosa sto facendo male qui?

Grazie per qualsiasi aiuto.
Doug

Modifica per ulteriori informazioni:

Si sta facendo un inserto in un (dimensione massima si avvicina) molto grande database di FoxPro. Il file ha circa 200 campi e quasi altrettanti indici su di esso.
E prima di chiedere, no non posso cambiare la struttura di esso come è stato qui prima che io fossi e v'è una tonnellata di codice legacy colpirlo. Il primo problema è, al fine di ottenere un nuovo ID devo prima trovare il max (id) nella tabella quindi incrementare e checksum esso. Questo richiede circa 45 secondi. Poi il primo inserto è semplice e l'inserto di quel nuovo ID e un campo enterdate. Questa tabella non è / non può essere messo in un DBC in modo che esclude gli ID di auto-generazione e simili.

@ joshua.ewer
Hai la proccess corretta e penso che per il breve termine mi limiterò a disattivare il pulsante di salvataggio, ma cercherò nella vostra idea di passare in una coda. Avete riferimenti a MSMQ che dovrei dare un'occhiata?

È stato utile?

Soluzione

Tutti gli altri, voi compresi, ha affrontato i problemi di fondo (tempo di inserimento, il motivo per cui si sta facendo un inserto, quindi aggiornare), quindi mi bastone con solo i problemi tecnici con la soluzione proposta. Quindi, se ho il diritto di flusso:

  • Discussione 1: immissione dei dati per iniziare record

  • Discussione 2: Background chiamate al DB per recuperare nuova Id

  • Il pulsante Salva è sempre abilitato, se l'utente cerca di salvare prima di Discussione 2 Completa, si mette # 1 di sonno per 200 ms?

Il più semplice, non è migliore, risposta è di appena hanno il pulsante disattivato, e hanno quel filo fare un callback a un delegato che abilita il pulsante. Essi non possono avviare l'operazione di aggiornamento fino a quando sei sicuro che le cose siano impostati in modo appropriato.

Anche se, credo che una soluzione molto migliore (anche se potrebbe essere esagerata se si sta solo costruendo un Q & front end D a FoxPro), sarebbe quello di gettare quelle operazioni di salvataggio in una coda. L'utente può digitare il più rapidamente possibile, quindi le richieste vengono messi in qualcosa come MSMQ e possono completare nel proprio tempo in modo asincrono.

Altri suggerimenti

1) Molti :), per esempio si potrebbe disabilitare il pulsante "Salva", mentre il filo sta inserendo l'oggetto, oppure si può impostare un thread di lavoro che gestiscono una coda di "salvare le richieste" (ma penso che il problema qui è che l'utente desidera modificare il record appena creato, in modo da disattivare il pulsante forse è meglio)

2) Penso che abbiamo bisogno un po 'di codice per essere in grado di capire ... (o forse è un problema di sincronizzazione, io non sono un fan bug di fili troppo)

btw, io proprio non capisco il motivo per cui un inserto dovrebbe prendere in modo long..I pensare che si dovrebbe verificare che il codice in primo luogo! <- proprio come Charles dichiarato prima (mi dispiace, dind leggere il post):)

futuro piuttosto che un'azione ThreadPool grezzo. Eseguire il futuro, permettono all'utente di fare ciò che vogliono, quando colpiscono Salva al 2 ° disco, richiedere il valore del futuro. Se il primo inserto finito già, si otterrà l'ID subito e il 2 ° inserto sarà permesso di dare il via. Se si sta ancora aspettando il 1 ° operazione, il futuro sarà bloccare fino a quando non è disponibile, e poi la seconda operazione in grado di eseguire.

Non stai salvando qualsiasi momento, a meno che l'utente è più lento rispetto l'operazione.

In primo luogo, si dovrebbe probabilmente scoprire, e risolvere, il motivo per cui un inserto sta prendendo così tanto tempo ... 50-75 secondi è irragionevole per qualsiasi database moderna per un unico inserto di fila, e indica che qualcosa ha bisogno di essere indirizzata, come indici, o il blocco ...

In secondo luogo, perché stai inserendo il record prima di avere i dati? Normalmente, le applicazioni di immissione dati sono codificati in modo tale che l'inserto non viene tentata fino a quando tutti i dati necessari per l'inserto sono state raccolte da parte dell'utente. State facendo questo perché si sta cercando di ottenere il nuovo ID indietro dal database prima, e poi "aggiornare" il nuovo record vuoto con i dati inseriti dall'utente successive? Se è così, quasi ogni fornitore di database ha un meccanismo in cui è possibile fare l'inserto solo una volta, senza conoscere il nuovo ID, e hanno il database restituisce il nuovo ID così ... Cosa fornitore del database stai usando?

È una soluzione come questo possibile:

pre-calcolare gli ID univoci prima che un utente inizia anche da aggiungere. Mantenere un elenco di ID univoco del già presenti nella tabella, ma sono effettivamente segnaposto. Quando un utente sta cercando di inserire, riservare loro uno degli ID univoci, quando l'utente preme risparmiare, ora sostituire il segnaposto con i loro dati.

PS: E 'difficile da confermare, ma essere consapevoli del seguente problema di concorrenza con quello che lei propone (con o senza fili): L'utente A, comincia ad aggiungere, l'utente B inizia ad aggiungere, l'utente A calcola ID 1234 come l'ID libera massima, l'utente B calcola ID 1234 come l'ID libera max. L'utente A inserisce ID 1234, l'utente B inserisce ID 1234 = Boom!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top