나는거야 가서 큰 가정 (모든 단서는 그 방향으로 포인트)합니다
난 당신이 윈도우 폼에이 모든 일을하는지 추정하고있어 그리고 당신은 GUI를 싶습니다 Thread.Sleep() 호출 도중 멈추지 않는가? 그 경우라면 당신은이 방법을 쓸 수있다 :
public static class Foo {
public static void MySleep(int milliseconds) {
int startTick = Environment.TickCount;
while (Environment.TickCount - startTick < milliseconds)
Application.DoEvents();
}
}
을 다음 Foo.MySleep 호출로 Thread.sleep를 호출을 대체 (그러나 전체 과정을 수 있습니다 Application.DoEvents의 의미의을 조심 예방 조치를 취하지 않으면이 작업을 수행하지 않는 것이 좋습니다. 예를 들어 func 테스트를 호출하는 단추를 항상 비활성화해야합니다 (예 :)테스트이 실행 중입니다. 왜냐하면 결코 끝나지 않는 재귀에서 반복 실행될 수 있기 때문입니다) :
func test()
for(int i=0;i<100;i++){
func A()
Foo.MySleep(20 * 1000);
func B()
Foo.MySleep(45 * 1000);
func C()
Foo.MySleep(2 * 60 * 1000);
}//repeat for 100 times
이렇게하는 또 다른 방법이 있습니다. 보조 스레드 및 일부 Control.Invoke 호출이 관련됩니다. 또한 표준 System.Thread.Sleep (int 밀리 초) 메서드를 사용할 수 있습니다.
그리고이 같은 간다 :
public class Form1 : Form {
public void triggerTestAndReturnImmediately() {
new Thread(start:() => {
Action callA =() => funcA();
Action callB =() => funcB();
Action callC =() => funcC();
for(int i=0;i<100;i++){
this.Invoke(callA);
Thread.Sleep(20 * 1000);
this.Invoke(callB);
Thread.Sleep(45 * 1000);
this.Invoke(callC);
Thread.Sleep(2 * 60 * 1000);
}//repeat for 100 times
}).Start();
}
}
은 "this.Invoke (someDelegate)"비트는 방법 "triggerTestAndReturnImmediately는"양식 서브 클래스의 일원이라는 사실에 근거하고있다을 "이" Form 인스턴스입니다.
여기서 계속되는 것은 실제 작업자 (funcA, funcB, funcC)의 대기 작업 + 트리거를 별도의 스레드에서 실행한다는 것입니다. 왜 당신은 실제 근로자가 아닌 실제 근로자의 삼총사 만 운영합니까? 왜냐하면 당신은 그 기능들로부터 GUI 객체에 접근 할 가능성이 가장 높기 때문에 WinForms (그리고 많은 다른 .NET 또는 그 외의 .NET GUI 프레임 워크에서는 허용되지 않습니다).
GUI 스레드 (질문에서 지적한대로)는 해당 기능을 실행하는 데 99 %의 시간이 소요되어야합니다. 따라서 this.Invoke (someDelegate) 호출을 자유롭게 사용해야합니다.
앞에서 언급 한 것과 동일한 예방 조치를 취해야하지만 모든 내용은 사용자에게 달려 있으며 응용 프로그램에서 수행해야 할 사항입니다. 단추의 Click 이벤트 처리기를 triggerTestAndReturnImmediately으로 호출하고 프로세스 중에이 단추를 사용하지 않으려면 단추를 사용하지 않도록 설정하고 다시 사용하도록 설정 하시겠습니까?
는이 작업을 수행 할 경우 : triggerTestAndReturnImmediately 방법은 그 이름에서 알 수 있듯이 그냥 무엇 않기 때문에
void buttonBar_Click(object sender, EventArgs e) {
this.buttonBar.Enabled = false;
this.triggerTestAndReturnImmediately();
this.buttonBar.Enabled = true;
}
은 즉, 어떤 좋은 일을하지 것이다 : "즉시 반환".
그럼 어떻게하지 않으시겠습니까? 당신이 뭔가를 할 수 있습니다 :
void buttonBar_Click(object sender, EventArgs e) {
this.triggerTestAndReturnImmediately();
}
public void triggerTestAndReturnImmediately() {
this.buttonBar.Enabled = false;
new Thread(start:() => {
Action callA =() => funcA();
Action callB =() => funcB();
Action callC =() => funcC();
Action reenableButton =() => this.buttonBar.Enabled = true;
for(int i=0;i<100;i++){
this.Invoke(callA);
Thread.Sleep(20 * 1000);
this.Invoke(callB);
Thread.Sleep(45 * 1000);
this.Invoke(callC);
Thread.Sleep(2 * 60 * 1000);
this.Invoke(reenableButton);
}//repeat for 100 times
}).Start();
}
또한 만들 호출 순서가 일부 마침내 문 또는 다른 체조를 시도하여 충돌 여부 항상 버튼을 다시 활성화해야합니다.
그래서 내가하고있는 예방 조치가 무엇인지 아이디어를 얻을 수 있다고 생각합니다. 귀하의 앱이 원하는 것을 따라 달라집니다.
왜 Thread.Sleep을 사용할 수 없습니까? 기다리는 동안 스레드를 해제하므로 지연이 필요한 경우 이상적으로 보입니다. – driis
왜 Thread.Sleep을 사용하고 싶지 않으십니까? 그것이 정확하게 설계된 것입니다. –
@driis : 스레드를 "해제"하지 않습니다. 다른 작업에서 스레드를 사용할 수있는 것과는 다릅니다. 중요한 CPU를 사용하지는 않지만 "해제"한다고는하지 않습니다. –