2009-04-20 5 views
1

알고리즘이 있습니다. 어떤 시점에서 일시 중지 한 다음 사용자가 버튼을 누르면 계속 진행하고 싶습니다. 어떻게해야합니까? 나는 문서를 열람하고 인터넷을 검색했지만 아직 행운은 없다. (pauza, 그냥 상수 세르비아어 일시 정지를 의미) 내가 잠을 사용 지금버튼을 누를 때까지 프로그램 실행을 일시 중지하는 방법?

 if A[i]>A[i+1] 
     then 
      begin 
      Zameni(i,i+1); 
      done:=true; 

      sleep(pauza); 

      br:=br+1; 
      end; 

:

여기에 관련 코드 싹둑입니다. 이상적으로, 그 라인을 그 간격 동안 잠들 수있는 절차로 바꾸거나 구성 설정에 따라 버튼을 누를 때까지 기다리는 것이 좋습니다.

EDIT1 : 아 그래, 명확하지 않은 경우 - 그래픽 응용 프로그램이지 콘솔이 아니므로 "readln"을 두드리는 것은 (슬프게도) 작동하지 않습니다.

답변

0

좋은 응용 프로그램 디자인으로 권장하지 않지만 다른 제안 사항 중 어느 것도 적합하지 않은 경우이 방법을 선호 할 수 있습니다.

클래스/양식에 '일시 중지 : 부울'입력란을 추가하고 '계속'버튼을 추가하십시오.

작업을 시작할 때 일시 중지를 거짓으로 설정하고 Continue.Enabled : = False로 설정하십시오.

코드가 일시 중지하려는 부분에 도달

: 당신의 버튼을 계속 이벤트 핸들러에서

Paused := True; 
Continue.Enabled := True; 
while Paused do 
begin 
    sleep(100); 
    Application.ProcessMessages; 
end; 

을 :

procedure Form1.ContinueClick(Sender: TObject); 
begin 
    Paused := False; 
    Continue.Enabled := False; 
end; 

내가 전에 꽤하지 말했듯이,하지만 그것은을 얻어야한다 일 끝났어.

+2

Sleep() 호출은 사용자가 방금 만든 버튼을 누를 수 없으므로 방금 무한 루프를 만들었습니다. 최소한 Application.ProcessMessages() 호출을 추가하십시오. 그럼에도 불구하고 그것은 끔찍한 해결책이 될 것입니다. – mghie

+0

Application.ProcessMessages를 포함하도록 답장을 업데이트했습니다. –

+0

mghie와 동의해야 할까봐 두려워합니다.이 솔루션의 문제점은이 루프 중에 앱이 CPU 사이클의 거의 100 %를 사용한다는 것을 알 수 있다는 것입니다. –

-1

그냥 사용 ReadLn;

ShowConsole("Enter to continue."); 
ReadLn; 
5

이는 이벤트 중심 프로그래밍을 수행하는 방식이 아닙니다. 일시 정지 지점까지 처리하고 그 지점에서 기능을 종료해야합니다. 버튼 누름 이벤트 핸들러에서 나머지 처리를 수행합니다. 이는 사용자가 버튼을 누를 때만 발생합니다. OnTimer 이벤트에서 동일한 코드를 호출하여 지정된 시간 이후에 처리를 계속할 수 있습니다. 당신은 우리가 즉


    procedure TForm1.Pause1Click(Sender: TObject); 
    begin 
    // A dialog box will halt thread execution 
    Windows.MessageBox(0, 'Paused ...' + sLineBreak + 'Press Enter to Continue', 
     '', MB_OK); 
    end; 

개 이상의 스레드가있는 경우에 아마 단지 당신이 할 수있다,하지만 현재의 thread를 정지 해, 간단한 메시지 상자가 확인 될 것이다, 무엇 인 대화를 시작할 수

+0

예, 그렇습니다. for 루프의 안쪽 부분입니다. 더 도움이된다면 전체 기능을 게시 할 수 있습니다. – VPeric

+2

디자인을 다시 생각해 봐야 할 것 같은데요. 이벤트 기반 (예 : GUI) 코드의 큰 루프는 별도의 스레드에 있지 않는 한 나쁜 생각입니다. –

+0

음, 나는 주요 질문을 벗어나고 싶지는 않았지만 다양한 정렬 알고리즘이 작동하는 방법을 설명하는 프로그램을 만들었습니다. (다양한 색의 그래프를 뒤섞어서 - 퀵소트의 Wikipedia 페이지에서 영감을 얻으십시오) 루프가 필요합니다. 아이디어는 사용자가 자신의 페이스대로 이해할 수 있도록 정렬 절차를 진행하도록하는 것입니다. – VPeric

0

더 복잡한 것을 시도하고 싶다.

+0

그것은 하나의 스레드이며, 예, ShowMessage는 내가 필요로하는 것을 수행합니다. 문제는보기를 가리고보기가 흉하게 보입니다. 다른 모든 것들이 실패한다면, 나는 그것을 향해 갈 것입니다 (나는 그것이 나타날 곳을 결정하는 방법이 있다고 생각합니다), 그러나 그것은 사용자 입장에서 볼 때 특히 직관적이지 않습니다. 나는 그가 "정상적인"버튼을 누를 수 있다면 더 좋을 것입니다. – VPeric

1

i를 정적 변수에 저장하십시오. 루프 내부에서 일시 중지 플래그 (일시 중지 버튼으로 설정)에 대한 확인을 추가하십시오. 플래그가 true이면 함수를 종료하십시오. 일시 정지 버튼을 다시 클릭하면 기능이 다시 호출됩니다. 내가> 0이라면 i의 값을 확인하십시오. 중단 한 위치의 루프를 입력하십시오.

루프가 성공적으로 완료되면 i를 0으로 재설정하십시오.

+0

여기에 가장 좋은 제안이 있다고 생각합니다. –

2

TThread 클래스에 대한 스레드 및 기본 제공 일시 중단/다시 시작 기능을 사용하십시오. Jens Borrisholt는 about.com here에 관한 작은 예제 기사를 작성하여 이런 종류의 작업을 수행했습니다.

응용 프로그램에서 ProcessMessage 위치를 여러 개 소개하면 양식을 닫을 때 실행중인 다른 이벤트의 코드 실행에 문제가 발생할 수 있습니다.예를 들어, ProcessMessage "sleep"모드에서 양식을 닫은 경우 스택을 푸는 좋은 방법이 없습니다.

정상적인 디스플레이를 열지 않기 때문에 DirectX/OpenGL을 사용하는 경우 MessageDialog가 작동하지 않을 수 있습니다. MessageDialog를 호출하면 DirectX보기의보기가 일반 데스크탑보기 (추악하지만 실행 가능)로 전환되거나 DirectX에서 표시 모드를 변경하지 않고 일반 바탕 화면보기에 메시지가 표시 될 수 있습니다 (사용자가 프롬프트를 볼 수 없게 만듭니다). Dx에서 작업 한 이후로 오랜 시간이 걸렸지 만보기 모드를 변경하는 데 실패하면 문제가 있음을 기억합니다.

편집 : 알렉산더가 지적했듯이 스레드는 어디에서나 일시 중지하면 안됩니다 (즉, 스레드 A는 스레드 A를 일시 중단 할 수 있지만 스레드 B는 일시 중단 할 수 없음). GUI 스레드에서 정렬 스레드를 일시 중단하려면 정렬 스레드에 메시지를 보내고 정렬 스레드 내부에서 일시 중단을 처리하십시오. 그의 링크에는 이것이 왜 그렇게 중요한지에 대한 토론이 포함되어 있습니다.

+0

그가 달성하고자하는 것에 너무 복잡하지 않습니까? –

+0

일시 중지 및 이력서는 디버거가 아닌 다른 용도로 사용 된 적이 없습니다. –

0

스레드 접근 방식에 동의하는 동안 suspend/resume을 사용하는 것은 매우 나쁜 생각이라고 생각합니다. 이유는 다음과 같습니다. http://blogs.msdn.com/oldnewthing/archive/2003/12/09/55988.aspx

스레드를 만들고 이벤트를 사용하여 스레드를 일시 중지/다시 시작합니다. 단순한. BTW, AsyncCalls와 같은 것을 사용하여 스레드 생성을 더 쉽게 만들 수 있습니다 (TThread 클래스는 필요하지 않습니다).

별도의 스레드를 만드는 것이 다른 이유 때문에 유용합니다. 백그라운드에서 무거운 계산을 할 수 있으므로 UI를 방해하지 않습니다. 앱이 원활하게 반응합니다.

+1

그 기사에서 진술되지 않은 내용이 있었기 때문에 첫 번째와 다섯 번째 주석에 언급되어 있긴하지만 그것을 놓쳤다는 것은 이해할 수 있습니다. 스레드가 스스로를 일시 중단하는 것은 완전히 안전합니다. 아마도 스레드의 다른 활동을 방해 할 수 없기 때문입니다. 스레드는 정렬의 한 단계를 수행 한 다음 자체를 일시 중단합니다. –

+0

이 링크는 실제로 이전 답변의 예에 대한 응답이었습니다.) – Alex

관련 문제