Questo thread.abort () è normale e sicuro?

Ho creato un controllo di autocompletamento personalizzato, quando l’utente preme un tasto interroga il server di database (utilizzando Remoting) su un altro thread. Quando l’utente digita molto velocemente, il programma deve annullare la richiesta / thread in esecuzione in precedenza.

In precedenza l’ho implementato come AsyncCallback, ma trovo ingombrante, troppe regole domestiche da seguire (es. AsyncResult, AsyncState, EndInvoke) oltre a dover rilevare il thread dell’object BeginInvoke, in modo da poter terminare il thread in esecuzione in precedenza . Inoltre, se ho continuato AsyncCallback, non c’è alcun metodo su quelle AsyncCallbacks che possono terminare correttamente il thread in esecuzione in precedenza.

EndInvoke non può terminare il thread, completerebbe comunque l’operazione del thread da terminare. Vorrei ancora finire usando Abort () sul thread.

Così ho deciso di implementarlo solo con approccio Pure Thread, senza AsyncCallback. Questo thread.abort () è normale e sicuro per te?

public delegate DataSet LookupValuesDelegate(LookupTextEventArgs e); internal delegate void PassDataSet(DataSet ds); public class AutoCompleteBox : UserControl { Thread _yarn = null; [System.ComponentModel.Category("Data")] public LookupValuesDelegate LookupValuesDelegate { set; get; } void DataSetCallback(DataSet ds) { if (this.InvokeRequired) this.Invoke(new PassDataSet(DataSetCallback), ds); else { // implements the appending of text on textbox here } } private void txt_TextChanged(object sender, EventArgs e) { if (_yarn != null) _yarn.Abort(); _yarn = new Thread( new Mate { LookupValuesDelegate = this.LookupValuesDelegate, LookupTextEventArgs = new LookupTextEventArgs { RowOffset = offset, Filter = txt.Text }, PassDataSet = this.DataSetCallback }.DoWork); _yarn.Start(); } } internal class Mate { internal LookupTextEventArgs LookupTextEventArgs = null; internal LookupValuesDelegate LookupValuesDelegate = null; internal PassDataSet PassDataSet = null; object o = new object(); internal void DoWork() { lock (o) { // the actual code that queries the database var ds = LookupValuesDelegate(LookupTextEventArgs); PassDataSet(ds); } } } 

GLI APPUNTI

Il motivo per cui si annulla il thread precedente quando l’utente digita le chiavi in ​​successione, non è solo per impedire l’aggiunta di testo, ma anche per cancellare il precedente roundtrip della rete, quindi il programma non consumerà troppa memoria derivante da successive operazione di rete.

Sono preoccupato se evito del tutto thread.Abort (), il programma potrebbe consumare troppa memoria.

ecco il codice senza il thread.Abort (), utilizzando un contatore:

 internal delegate void PassDataSet(DataSet ds, int keyIndex); public class AutoCompleteBox : UserControl { [System.ComponentModel.Category("Data")] public LookupValuesDelegate LookupValuesDelegate { set; get; } static int _currentKeyIndex = 0; void DataSetCallback(DataSet ds, int keyIndex) { if (this.InvokeRequired) this.Invoke(new PassDataSet(DataSetCallback), ds, keyIndex); else { // ignore the returned DataSet if (keyIndex < _currentKeyIndex) return; // implements the appending of text on textbox here... } } private void txt_TextChanged(object sender, EventArgs e) { Interlocked.Increment(ref _currentKeyIndex); var yarn = new Thread( new Mate { KeyIndex = _currentKeyIndex, LookupValuesDelegate = this.LookupValuesDelegate, LookupTextEventArgs = new LookupTextEventArgs { RowOffset = offset, Filter = txt.Text }, PassDataSet = this.DataSetCallback }.DoWork); yarn.Start(); } } internal class Mate { internal int KeyIndex; internal LookupTextEventArgs LookupTextEventArgs = null; internal LookupValuesDelegate LookupValuesDelegate = null; internal PassDataSet PassDataSet = null; object o = new object(); internal void DoWork() { lock (o) { // the actual code that queries the database var ds = LookupValuesDelegate(LookupTextEventArgs); PassDataSet(ds, KeyIndex); } } }