2014-07-26 5 views
-1

버튼을 클릭하여 스레드를 종료하고 싶습니다. 쓰래드가 사용자 인터럽트없이 정상적으로 작동한다면 괜찮습니다.하지만 사용자가 쓰레드를 중단시켜야 할 때가 있습니다. 이것이 사용자가 쓰레드를 중단시키는 방법입니다.델파이에서 스레드 외부에서 직접 스레드를 종료 할 수 있습니까?

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, mmsystem, ExtCtrls; 

type 
    TForm1 = class(TForm) 
    Image1: TImage; 
    procedure Image1Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    end; 

type 
    hangth = class(TThread) 
    private 
    { Private declarations } 
    protected 
    procedure Execute; override; 
    procedure play; 
    end; 

var 
    Form1: TForm1; 
    played: boolean; 
    szalhang: hangth; 

implementation 

{$R *.dfm} 

procedure hangth.play; 
begin 
    played := true; 
    szalhang.Terminate; 
end; 

procedure hangth.Execute; 
begin 
    played := false; 
    SndPlaySound(pchar('hang.wav'), SND_SYNC); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    played := true; 
end; 

procedure TForm1.Image1Click(Sender: TObject); 
begin 
    if played = true then begin 
    szalhang := hangth.Create(true); 
    szalhang.Resume; 
    end else begin 
    szalhang.Terminate(); 
    // here i want to terminate thread, but it doesn't want to be killed. 
    end; 
end; 

end. 
+0

을 그럼에도 불구하고 우리는 여전히 문제가 무엇인지 모르는 : 당신은 TForm을 가지고, 당신은 예를 들어, 델파이의 TMediaPlayer 구성 요소를 사용하는 것이 좋습니다. "스레드 외부의 스레드를 직접 종료"하는 것은 무엇을 의미합니까? –

+0

버튼을 클릭하여 스레드를 종료하고 싶습니다. 쓰래드가 사용자 인터럽트없이 정상적으로 작동한다면 괜찮습니다.하지만 사용자가 쓰레드를 중단시켜야 할 때가 있습니다. 이것이 사용자가 쓰레드를 중단시키는 방법입니다. – user3880482

+0

좋습니다. 좋은 시작입니다. 하지만 위의 코드를 수정하여 컴파일 할 수 있습니까? 당신은 그것이 효과가 있다고 말하는데, 우리 모두는 그것이 효과가 없다는 증거를 보았습니다. –

답변

0

당신이 TThread.Terminate() 전화, 그것이 사실로 TThread.Terminated 속성을 설정하고 다른 아무것도하지 않는다 :

여기에 내가 테스트 내 코드입니다. TThread.Execute() 코드는 주기적으로 TThread.Terminated 속성을보고 True 일 때 정상적으로 종료해야합니다. 그러나이 상황에서는 SndPlaySound()이 스레드를 차단하고 있기 때문에 가능하지 않으며 SND_SYNC 모드에서 실행 중일 때 SndPlaySound()을 인터럽트 할 방법이 없습니다. 유일한 옵션은 Win32 API TerminateThread() 함수를 사용하여 스레드의 무차별 강제 종료를 수행하는 것입니다.

분명히 오디오 재생을 제어하고 오디오 재생이 완료된 것을 감지해야하므로 SndPlaySound()은 사용자의 요구에 가장 적합한 솔루션이 아닙니다.

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.MPlayer; 

type 
    MPlayerState = (mpsClosed, mpsOpened, mpsPlaying); 

    TForm1 = class(TForm) 
    Image1: TImage; 
    MediaPlayer1: TMediaPlayer; 
    procedure MediaPlayer1Notify(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure Image1Click(Sender: TObject); 
    private 
    { Private declarations } 
    State: MPlayerState; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm56.FormCreate(Sender: TObject); 
begin 
    State := mpsClosed; 
    MediaPlayer1.FileName := 'C:\full path to\hang.wav'; 
end; 

procedure TForm56.MediaPlayer1Notify(Sender: TObject); 
begin 
    case MediaPlayer1.Mode of 
    mpStopped, mpPlaying: 
     State := mpsOpened; 
    end; 
end; 

procedure TForm1.Image1Click(Sender: TObject); 
begin 
    if State = mpsClosed then 
    begin 
    MediaPlayer1.Notify := False; 
    MediaPlayer1.Wait := True; 
    MediaPlayer1.Open; 
    State := mpsOpened; 
    end; 

    if State = mpsOpened then 
    begin 
    MediaPlayer1.Notify := True; 
    MediaPlayer1.Wait := False; 
    MediaPlayer1.Play; 
    if MediaPlayer1.Error = 0 then 
     State := mpsPlaying 
    end else 
    begin 
    MediaPlayer1.Notify := False; 
    MediaPlayer1.Wait := True; 
    MediaPlayer1.Stop; 
    State := mpsOpened; 

    MediaPlayer1.Notify := False; 
    MediaPlayer1.Wait := True; 
    MediaPlayer1.Close; 
    State := mpsClosed; 
    end; 
end; 

end.