TThread.resume è obsoleto in Delphi-2010 che cosa dovrebbe essere usato sul posto?

StackOverflow https://stackoverflow.com/questions/1418333

  •  07-07-2019
  •  | 
  •  

Domanda

Nella mia applicazione multithread

Uso TThread.suspend e TThread.resume

Da quando ho spostato la mia applicazione su Delphi 2010 ricevo il seguente messaggio in guerra

[Avviso DCC] xxx.pas (277): il simbolo W1000 "Riprendi" è obsoleto

Se Resume è deprecato, quale dovrebbe essere usato sul posto?

MODIFICA 1:

Uso il comando Riprendi per avviare il thread, poiché viene creato con "CreateSuspended" impostato su True e Suspending prima di terminare il thread.

MODIFICA 2:

Ecco un link al manuale di delphi 2010

È stato utile?

Soluzione

Charles, se leggi il codice della classe TThread, trovi la risposta.

   TThread = class  
   private type  

..
..
..   
   public  
     constructor Create(CreateSuspended: Boolean);  
     destructor Destroy; override;  
     procedure AfterConstruction; override;  
     // This function is not intended to be used for thread synchronization.  
     procedure Resume; deprecated;  
     // Use Start after creating a suspended thread.  
     procedure Start;  
     // This function is not intended to be used for thread synchronization.  
     procedure Suspend; deprecated;  
     procedure Terminate;  

Vedi questo link http://wings-of-wind.com/2009/08/28/rad-studio-2010-community-pulse-the-day-after-part-2/

Modifica

Se è necessario sincronizzare i thread, è possibile utilizzare uno schema basato su TMutex, TEvent e le sezioni critiche.

Ciao.

Altri suggerimenti

Usa TThread.Start invece di .Resume

- EDIT-- Ovviamente Start può essere utilizzato solo con Delphi 2010 (e successivamente, presumibilmente) per avviare un thread che è stato creato sospeso (dove avresti usato Resume prima).

L'utilizzo di Riprendi / Sospendi (o le corrispondenti funzioni WinAPI) per la sincronizzazione dei thread NON è raccomandato. Guarda la discussione qui (dai un'occhiata ai commenti di Barry Kelly).

Sospendi e Riprendi erano (o erano soliti) potenzialmente rotti nella classe TThread (se guardi la fonte vedrai che il metodo Suspend imposta direttamente e incondizionatamente un valore booleano sullo stato sospeso del thread indicato piuttosto che derivare più efficacemente questo stato dal conteggio dell'esecuzione sull'handle del thread. Ironicamente il metodo Riprendi utilizza questo indicatore più robusto su < em> aggiorna lo stato booleano sospeso.

Questo è probabilmente il motivo per cui sono stati deprecati. È anche il motivo per cui ho implementato la mia classe per incapsulare un thread di Windows con un meccanismo di sospensione e ripresa più robusto, nonché la possibilità di Riavviare una volta completato.

Non sono sicuro del motivo per cui la loro deprecazione è presumibilmente correlata alla sincronizzazione. La sospensione e la ripresa dei thread non è necessariamente correlata alla sincronizzazione, anche se posso vedere come potrebbe essere. È interessante notare che i metodi equivalenti nella classe Thread .NET framework sono similmente contrassegnati come obsoleti. E gli stessi commenti w.r.t sincronizzazione appaiono nella documentazione dell'API di Windows per la sospensione / ripresa del thread.

Se l'utilizzo di metodi obsoleti ti rende nervoso e desideri comunque sospendere / riprendere, puoi sempre utilizzare l'API di Windows per sospendi e riprendi il thread facendo riferimento alla relativa maniglia .

Il codice di controllo del comportamento del thread dovrebbe trovarsi in una procedura di thread. Utilizzare gli oggetti di sincronizzazione appropriati e le chiamate API corrispondenti per sospendere / riprendere l'esecuzione del thread. Farlo dall'esterno è una pratica pericolosa. Quindi c'è stata una decisione di privarlo.

Nel caso in cui tutto ciò che volevi fare fosse sbarazzarti dei suggerimenti del compilatore

(1) Per eliminare il suggerimento del compilatore quando Avvio di una discussione ...

sostituire

MyThread := TMyThread.Create(True);
MyThread.Resume;

con

MyThread := TMyThread.Create(True);
MyThread.Start;

(2) Per eliminare il suggerimento del compilatore quando Interrompi una discussione ...

sostituire

MyThread.Suspend;
MyThread.Terminate;

con

MyThread.Terminate;

Non è un grosso problema. Fai attenzione al tentativo di offuscamento .

Dovresti creare il thread come segue:

constructor TSignalThread.Create;
begin
 // create event handle first!
  FEventHandle := CreateEvent(
          {security}      nil,
          {bManualReset}  true,
          {bInitialState} false,
          {name}          nil);
  FWaitTime := 10;
  inherited Create({CreateSuspended}false);
end;

In questo modo non è necessaria una chiamata a Start.

Vedi http://www.gerixsoft.com/blog/delphi/creating- thread per una spiegazione del perché questo codice funziona.

Usa

Suspended := False; // Resume;

o

Start;

@mghie (un po 'tardi, lo so)

prendi ad esempio madexcept e simili. Se l'applicazione si arresta in modo anomalo e viene mostrata all'utente una segnalazione di bug, ciò significa che la finestra di dialogo attende l'input di utilizzo. In tal caso, l'arresto anomalo è il risultato di un'azione di thread (non necessariamente un crash del thread), se non si sospendono i thread, lo schermo verrà riempito con finestre di dialogo di segnalazione bug.

esempio 2: registrazione. per qualsiasi motivo particolare, almeno, avevo la necessità di registrare alcuni stati di esecuzione dei thread. Ciò include la traccia dello stack corrente. Ora, come dovresti (dovresti) sapere, non puoi farlo mentre il thread è in esecuzione perché durante il momento in cui raccogli informazioni su di esso, i thread continuano a fare cose in modo che al termine della raccolta, le informazioni raccolte non saranno coerenti. Quindi, è necessario sospendere il thread.

E posso continuare con esempi pratici sulla gestione dei thread. Certo, queste non sono cose che fai nella programmazione quotidiana, ma almeno il primo esempio sono sicuro che molti di voi stanno usando, anche se non ne sono a conoscenza. Debugger? di nuovo, li usi. In effetti, in tutti questi casi, TThread non viene utilizzato, poiché il lavoro viene eseguito sugli handle di thread. Quindi, in effetti, è difficile trovare un esempio valido dell'uso della sospensione di TThread. Ma le discussioni in generale, questa è un'altra storia.

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