진행률 표시줄 생성에 대한 질문안녕하세요. 진행률 표시줄과 "취소" 버튼이 있는 창을 만들었습니다. 의도는 사용자가 프로그램 실행을 중지할 수 있도록 하는 것입니다. 취소를 누르면 오류가 뜨는데 어떻게 해결해야할지 모르겠습니다. 내 스크립트의 단순화된 버전은 다음과 같습니다.
Names Default to Here(1);
//Define progress window
pwin = NewWindow("Progress",
SB_L = SpacerBox(Size(0, 15), Color("Green")),
ButtonBox("Cancel",
pwin << Close Window;
Stop();
)
);
//Sample Loop
For(i=1, i<=10, i++,
SB_L << Size(i*10, 15); //update the progress bar
Wait(1); //rest of loop
);루프가 실행되는 동안 취소를 누르면 다음 오류가 발생합니다.
deleted object reference: SB_L << Size(i * 10, 15) in access or evaluation of 'Glue' , pwin = New Window("Progress",
SB_L = Spacer Box(Size(0, 15), Color("Green")),
Button Box("Cancel",
pwin << Close Window;
Stop();
)
); /*###*/For(i = 1, i <= 10, i++,
SB_L << Size(i * 10, 15);
Wait(1);
) /*###*/;취소 버튼을 누르면 진행률 창이 닫히고 실행이 중지될 것으로 예상됩니다. 그러나 적어도 한 번의 반복 동안 계속되는 것처럼 보이고 For 루프의 SB_L << Size() 줄에서 실패합니다. 진행률 창이 닫히고 SB_L이 삭제되었기 때문에 실패하지만 Stop() 명령이 실행된 경우 이 줄이 실행되는 이유는 무엇입니까?
내 Stop() 명령 이후에도 프로그램 실행이 계속된다는 것이 맞습니까? 취소 버튼을 누른 후 SB_L << Size() 명령이 실행되지 않도록 하려면 어떻게 해야 합니까?
세부:
JMP 프로 15.2.1
맥 OS 빅서 v11.6
감사해요.
고급 통계 모델링자동화 및 스크립팅데이터 혼합 및 정리대량 맞춤화품질 및 프로세스 엔지니어링Re: 프로그레스 바 생성 질문입니다.불행하게도 본질적으로 잘못된 해킹을 하지 않고는 여기서 원하는 것을 할 수 없습니다.JMP 스크립트는 단일 스레드이며 취소 버튼이 있는 진행률 표시줄은 주로 메인 스레드에 GUI/이벤트 루프가 있고 작업자 스레드에 모든 스크립트와 함수 호출이 있는 다중 스레드 시스템에서만 의미가 있습니다.
이러한 경우에도 취소 등을 적절하게 처리하려면 일종의 센티넬이 필요합니다.취소 버튼이 스레드를 죽이는 것은 확실히 가능하지만 일반적으로 안전한 중지 경로(일종의 중단 분기)가 필요합니다.
JSL에서 이 작업을 수행할 수 있지만 다음 중 하나가 필요합니다. 기다리다( ... ) 진술 또는 <<업데이트 창() 둘 다 잠재적으로 심각한 결과를 초래할 수 있습니다.특히, 스크립트 내에서 변수 이름을 엉망으로 만들 수 있는 이벤트 루프 중에 의도하지 않게 실행되는 코드가 있을 수 있습니다. 예를 들어 그래픽 스크립트가 그래프에 존재하고 실행되는 경우(JMP는 그래픽 스크립트를 매우 적극적으로 실행함) 이러한 스크립트가 제어할 수 없는 다른 애드인에서 사용자 시스템에 존재할 수 있습니다.스크립트가 완료될 때까지 이벤트 루프에 다시 실행을 제공하지 않는 것이 가장 좋습니다(그리고 분명히 JMP가 정지된 것처럼 보이지 않도록 스크립트를 가능한 한 짧게 유지하는 것이 좋습니다).길고 짧은 것은 -- 이벤트 루프에 실행을 되돌려주지 마십시오.
저는 개인적으로 현시점(거의 2022년입니다!)에서 JSL 내에서 다중 스레드 실행 패러다임을 갖지 않는 것이 JMP 팀의 근시안적이라고 생각하지만 실제로는 그렇습니다.
한 가지 주의할 점은 외부 프로그램을 실행하고 STDOUT을 통해 IPC를 통해 대화할 수 있다는 것입니다.예를 들어 Python을 사용하여 일종의 장기 실행 작업을 수행하고 STDOUT을 사용하여 완료 시점을 알 수 있습니다(일종의 STDOUT 센티넬에서 JMP 스크립트를 시작할 수도 있음).
Re: 프로그레스 바 생성 질문입니다.예. 버튼 스크립트는 자체 "컨텍스트"에서 실행됩니다. wait 문을 실행하는 다른 스크립트가 있는지 전혀 모릅니다. 전역을 통해 통신할 수 있습니다. 그리고 이상한 가능성을 끝내기 위해 버튼 스크립트에서 대기를 사용하면 스크립트를 실행하는 창에서 닫기 X를 클릭할 수 있음을 의미합니다. 대기가 끝나면 jmp는 스크립트를 안전하게 중지하려고 시도합니다. 일반적으로 대기 중에 버튼 스크립트를 들고 있는 창이 닫히면 대기 후 다음 명령문이 실행되지 않습니다.
편집: 또한 취소 버튼 클릭을 처리하는 데 대기가 필요합니다.
Re: 프로그레스 바 생성 질문입니다.안녕 크레이지! 감사해요. 명확히 하기 위해 내가 추가한 "Wait(1)"은 이 데모에서 더 긴 명령 집합의 실행을 모방하고 "취소"를 클릭할 충분한 시간을 제공하여 문제를 재현할 수 있도록 하기 위한 것입니다. 하지만 대기가 스크립트의 필수 부분이 되도록 의도하지 않았습니다.
당신이 말하고 있다고 생각하는 것을 요약할 수 있다면:
취소 버튼은 스크립트 A(For 루프를 포함하는 기본 스크립트)와 독립적인 스크립트 B를 호출합니다. 스크립트 B의 중지 명령은 스크립트 B의 실행을 중지할 수 있지만 스크립트 A에는 영향을 미치지 않습니다.
더/적게 맞습니까?
Re: 프로그레스 바 생성 질문입니다.wait( n )은 JMP에서 가능한 한 피해야 하는 필요악입니다. 기다리는 동안 대기를 호출하는 스크립트는 OS가 클릭을 인식하거나 열려 있는 창을 표시하는 것과 같은 작업을 수행할 수 있는 동안 일시 중지됩니다. 클릭을 사용하여 첫 번째 스크립트의 환경을 건드리는 다른 스크립트(귀하의 예)를 시작할 수 있기 때문에 이상한 일이 발생할 수 있습니다. 귀하의 예에서 stop()은 두 번째 스크립트를 중지합니다. 전역 플래그를 설정할 수도 있습니다. 프로젝트가 전역 변수 추적에 대해 걱정할 만큼 충분히 큰 경우 이름 공간을 사용할 수도 있습니다.
그래서 일어날 수있는 이상한 일은 무엇입니까? 대부분 창이 닫히거나 디스플레이 상자가 삭제됩니다. 특히, wait(1)을 사용하는 스크립트가 있는 클릭 기능을 상상하고 0.5초 후에 버튼을 다시 클릭합니다. 스크립트의 두 번째 복사본이 첫 번째 내부에서 실행 중입니다. 원래 wait(1)은 두 번째 스크립트가 완료될 때까지 반환되지 않습니다. 두 번째 스크립트가 버튼이 있는 창을 닫는 경우 원래 스크립트 주변에는 어떤 환경이 있습니까? (대기 전과 같지 않습니다!) 정당한 이유 없이 대기가 필요한 스크립트를 작성하지 마십시오. 대부분의 경우 displaybox<<
Re: 프로그레스 바 생성 질문입니다.다른 흥미로운 것을 발견했습니다. 취소 버튼 스크립트에서 "pwin << Close Window()" 명령을 주석 처리하면 취소 버튼이 더 이상 실행을 중지하지 않습니다. Stop() 명령이 버튼에서 실행될 때 For 루프를 중지할 수 없는 것 같습니다. 이전에는 창을 제거하면 오류가 발생했기 때문에 취소 버튼으로 실행을 중지할 수 있었습니다.
Re: 프로그레스 바 생성 질문입니다.감사합니다 Ryan (및 Craige). 이것은 내가 확실히 고려하고 있는 옵션 중 하나지만 기본 스크립트 본문의 if 절에 플래그를 보내야 합니다. 내 소원은 취소 버튼에서 Stop() 명령을 사용하여 프로그램 실행을 중지하는 것입니다. 질문을 재구성할 수 있습니다. Stop() 명령이 실행을 중지하지 않는 이유는 무엇입니까?
Re: 프로그레스 바 생성 질문입니다.안녕 @nikles . 이 최근 게시물을 확인하고 싶을 수 있습니다. @Craige_Hales , 취소 버튼이 있는 진행률 표시줄 .