2009-07-26 6 views
18

Ho un programma che sta avendo qualche problema durante l'arresto, sollevando eccezioni che non posso risalire alla loro origine. Sembra essere correlato al tempo e non deterministico. Ciò si verifica dopo che tutte le risorse condivise sono state rilasciate e, poiché è in arresto, le perdite di memoria non sono un problema, quindi mi chiedo se c'è un modo per dire al programma di terminare immediatamente e in silenzio dopo aver rilasciato le risorse condivise, invece di continuare con la sequenza di spegnimento e dare una finestra di messaggio di eccezione.Come si annulla in modo pulito un programma Delphi?

Qualcuno sa come farlo?

+1

che tipo di programma è? Console app? Basato sulla domanda? Si sta tentando di eseguire il debug/in/il processo di spegnimento? –

+0

Basato sulla domanda, e sì, lo sono, e non funziona. Sembra essere correlato ai tempi, più il debugger è più o meno inutile in questa app. Vedere http://qc.embarcadero.com/wc/qcmain.aspx?d=76039 per il motivo. –

risposta

18

Dopo aver consultato il codice sorgente Run Time di Delphi e la documentazione Microsoft; Posso confermare i commenti di Mason e Paul-Jan.

La gerarchia di arresto è la seguente

Application.Terminate() 
    performs some unidentified housekeeping of application 
    calls Halt() 

    Halt() 
    calls ExitProc if set 
    alerts the user in case of runtime error 
    get rid of PackageLoad call contexts that might be pending 
    finalize all units 
    clear all exception handlers 
    call ExitprocessProc if set 
    and finally, call ExitProcess() from 'kernel32.dll' 

    ExitProcess() 
    unloads all DLLs 
    uses TerminateProcess() to kill the process 
+0

'TApplication.Terminate()' non chiama 'Halt()'. Chiama un elenco di proc termination, se impostato, e quindi invia un messaggio 'WM_QUIT' alla coda dei messaggi del thread chiamante. Quando 'TApplication.Run()' prende il 'WM_QUIT', interrompe il suo ciclo di messaggi ed esce, ritornando al blocco di codice principale del progetto che poi esce, attivando la pulizia del processo. –

4

Halt (0) era il buon vecchio modo di dire che il programma terminava con effetto immediato. Probabilmente c'è un modo più efficace di farlo con Delphi, ma sono sicuro al 95% che halt (0) funziona ancora. :-)

+1

Funziona sicuramente, ma eseguirà comunque un'elaborazione piacevole e pulita di tutte le parti di finissaggio e di exitprocs. Se uno di questi innesca il problema di Mason, è ancora nei guai. –

4

Nel caso in cui il suggerimento di HeartWare di utilizzare ExitProcess() non riesca, è possibile che si stiano utilizzando alcune DLL che non rispondono correttamente al DLL_PROCESS_DETACH. In tal caso, provare a utilizzare TerminateProcess (getCurrentProcess, 0);

Una volta che si ricorre a tali misure, ci si potrebbe chiedere se la parte "pulita" del titolo dell'argomento regga ancora al vaglio.

+2

Oh, poteva solo lavarsi le mani dopo averlo fatto - lo tiene pulito! – Arafangion

1

L'ultima volta che ho dovuto cercare un problema come questo era l'arresto causava un evento (ridimensiona? È passato un po 'di tempo) per sparare sulla finestra morente causando un tentativo di ridisegnare qualcosa che aveva bisogno di cose che già stato eliminato.