어떻게 항복하는 UI 스레드를 업데이트 UI 을 하고 있는 동안 일괄 처리에 WinForm 응용 프로그램?

StackOverflow https://stackoverflow.com/questions/106036

  •  01-07-2019
  •  | 
  •  

문제

나는 WinForms 작성된 응용 프로그램에서는 C#니다.NET3.5.실행 긴 일괄 처리 프로세스.내가 원하는 시간에 원하는 응용 프로그램를 업데이트 상태의 어떤 일괄 처리 프로세스입니다.는 가장 좋은 방법은 무엇입 업데이트 UI?

도움이 되었습니까?

해결책

BackgroundWorker 소리와 같은 개체를 원합니다.

다른 팁

빠르고 더러운 방법이 사용하는 Application.DoEvents() 그러나 이것이 문제를 일으킬 수 있습기 위해 이벤트를 처리합니다.하지 않는 것이 좋습니다 그래서

문제입니다 아마 당신을 항복하는 ui 스레드 그러나 당신이 처리하는 ui 스레드에서 그것을 차단을 처리하는 메시지입니다.당신이 사용할 수 있습 backgroundworker 구성 요소를 할 일괄 처리에 다른 쓰레드를 차단하지 않고 UI thread.

실행 긴 과정에서 백그라운드 스레드.배경을 작업자 클래스 쉬운 방법입니다 이렇게 제공합니다 단순한 지원을 위한 전송 진행 상황 업데이트 및 완료에 대한 이벤트는 이벤트를 처리기에서 근무하고 있으며 올바른 스레드습니다.이 코드는 깨끗하고 간결하고 있습니다.

을 표시하는 업데이트를 진행,바 또는 상태 표시줄 텍스트는 두 개의 가장 일반적인 접근한다.

중요한 것은 기억되는 경우 당신은 일을 하는 배경에서 스레드로 전환해야 합니다 UI 스레드에서 업데이트하기 위해 윈도우 컨트롤 등등.

을 쇠고기는 사람들이 말하는 것에 대해 DoEvents,여기에 설명의 어떤 일이 일어날 수 있습니다.

말 당신은 어떤 모양이 있는 데이터에 그것은 당신의 오래 실행되는 이벤트가 저장 또는 데이터베이스를 생성하는 보고서 그것을 기반으로 합니다.당신은 시작을 저장하거나 생성한 보고서는 정기적으로 당신은 전화 DoEvents 도록하면 그림입니다.

불행하게도 이 화면은 단지 그림,그것은 또한 사용자에 대한 대응 조치한다.이 때문에 DoEvents 중지 무엇을 하고 있는 지금 프로세스는 모든 windows 기를 기다리는 메시지를 처리하는 데 적용.이러한 메시지를 요청을 포함하여 다시 그리기뿐만 아니라,어떤 사용자 입력을 클릭하면,,등등.

그래서 예를 들어 있는 동안 데이터를 저장,사용하는 것과 같은 응용 프로그램을 보여달하는 대화 상자의 전혀 상관없이 오래 실행되는 작업(예를 들어 도울->대략).지금 당신이 반응하는 새로운 사용자 작업 이미 실행하는 오래 실행되는 작업입니다.DoEvents 반환됩니다 모든 이벤트를 기다리고 있었을 때라고 그것은 완료,그리고 당신의 장기 실행 작업은 계속됩니다.

어떤 경우에는 사용자가 닫지 않는 모달 대화?당신의 장기 실행한 작업을 기다립 영원까지 대화 상자를 닫습니다.만약 당신에 투입하는 데이터베이스를 들고 거래,지금 당신은 당신을 들고 거래를 열면 사용자가 갖는 커피입니다.하나의 트랜잭션 시대를 잃고 지속성,작동하거나 거래하지 않는 시간을 당신은 잠재적으로 교착 상태를 다른 사용자의 DB.

여기서 무슨 일이 벌어지고 있는 응용 프로그램.DoEvents 의 코드 재진입.시키 정의 .참고 몇 가지 포인트 정상에서의 기사는 코드를 재진입에 의하여,그것이 한다:

  • 해야 하지 않는 고정(또는 글로벌)금속 데이터입니다.
  • 해야만 작동에 제공된 데이터에 의해 발신번호를 입력하실 수 있습니다.
  • 지에 의존 자물쇠를 단일 리소스입니다.
  • 지 아닌 재진입 컴퓨터 프로그램 또는 루틴입니다.

그것은 오래 실행되는 코드에서는 데 적용은 작업에서만 데이터를 전달 메소드 호출자에 의해,유지하지 않는 정적 데이터,을 보유하고 잠금,그리고 호출만 다른 재진입 방법이 있습니다.

으로 많은 사람들이 여기서 말하고 있는,DoEvents 이어질 수 있는 아주 이상한 시나리오에 코드입니다.버그를 이어질 수 있습니다 매우 어려울 수 있습을 진단하고,귀하의 사용자가 당신에게 가능성이"아,이 일이 있었기 때문에 나를 클릭한이 없는 버튼을 하는 동안 기다리고 있었을 저장"을 선택합니다.

사용 backgroundworker 구성 요소를 실행하는 일괄 처리하는 별도의 스레드,이것 다음에 영향을 미치지 않습니다.

하고 싶어 다시 말하이 무엇 내 이전의 의견 제시 주의:을 피하십시오 DoEvents()가능할 때마다,이것은 거의 항상의 양식"해킹"및 원인 유지보수 악몽이다.

만약 당신이 갈 BackgroundWorker road(는 것이 좋),당신은 당신을 십자가 스레드를 호출하 UI 를 호출하려는 경우 어떤 방법이나 컨트롤의 속성,이들은 스레드-아핀과 호출해야 하에서 실을 만들어진다.사용을 제어합니다.Invoke()및/또는 제어합니다.BeginInvoke()으로 적합합니다.

실행하는 경우에는 배/는 worker 쓰레드,호출할 수 있습니다 Control.Invoke 중 하나에 당신의 UI 컨트롤을 실행하는 대리자 UI 에서 실을 뀁니다.

Control.Invoke 은 동기(할 때까지 기다립 대리인이 반환).원하지 않는 경우에 당신을 기다릴 사 .BeginInvoke() 만 큐의 명령입니다.

값의 .BeginInvoke() 를 확인 할 수있는 경우 방법이 완료되거나 때까지 기다려야 그것은 완료됩니다.

Backgroundworker, 고,당신은 또한 업데이트하려는 GUI 스레드에 의해 취급 ProgressChanged 이벤트(예,한 ProgressBar),요 WorkerReportsProgress=true, 또는 스레드가 진행 보고 죽을 것이 처음 호출을 시도 ReportProgress...

예외가 발생하지만,표시되지 않을 수도 있습니다면 당신은'때 던져'사용,출력이 스레드가 종료됩니다.

응용 프로그램.DoEvents()또는 실행하는 배치에서 별도의 thread?

DoEvents()이는 무엇을 찾고 있었지만 나도 backgroundworker 답변하기 때문에 보이는 좋아 좋은 해결책이 나는 조사할 것이 몇 가지 더 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top