2013-11-04 2 views
12

BackgroundWorker을 계속 실행할 수 있어야합니다. DoWork 이벤트에는 풀 스레드 프로세스가 포함되어 있으며 OnComplete은 내 UI를 업데이트합니다.BackgroundWorker 연속 실행

전체 프로그램이 멈추지 않고 BackgroundWorker.RunWorkerAsync() 메서드를 무한 루프 할 수있는 방법을 찾을 수 없었습니다. 어떤 도움이라도 대단히 감사하겠습니다.

+1

당신은 당신의'BackgroundWorker'으로 무엇을 원하는가? 왜 계속해서 실행하고 싶습니까? –

+1

"일반"스레딩을 사용하지 않는 이유는 무엇입니까? 또는 어쩌면 작업이나 뭐 .. 정확히 당신이 BackgroundWorker가 필요한 이유는 무엇입니까? AFAIK는 이런 식으로 사용되는 것을 의미하지 않았습니다. – walther

+1

주 스레드 (UI)로 다시 통신하고 ReportsProgress를 사용하여 BackgroundWorker를 실행 상태로 유지할 수 있습니다. – Paparazzi

답변

23

DoWork-Method에서 루프를 만들어야합니다. UI를 업데이트하려면 ProgressChanged-Method를 사용하십시오. 여기에 작은 예는이 프로그램이 동결되어있는 경우, 그것은 당신의 무한 루프 배경 작업자 스레드가 CPU를 100 % 사용하여 회전하기 때문에 될 수

public Test() 
    { 
     this.InitializeComponent(); 
     BackgroundWorker backgroundWorker = new BackgroundWorker 
      { 
       WorkerReportsProgress = true, 
       WorkerSupportsCancellation = true 
      }; 
     backgroundWorker.DoWork += BackgroundWorkerOnDoWork; 
     backgroundWorker.ProgressChanged += BackgroundWorkerOnProgressChanged; 
    } 

    private void BackgroundWorkerOnProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     object userObject = e.UserState; 
     int percentage = e.ProgressPercentage; 
    } 

    private void BackgroundWorkerOnDoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = (BackgroundWorker) sender; 
     while (!worker.CancellationPending) 
     { 
      //Do your stuff here 
      worker.ReportProgress(0, "AN OBJECT TO PASS TO THE UI-THREAD"); 
     }   
    } 
+5

'while (true)'대신'((BackgroundWorker) sender) .CancellationPending'을 사용하면 취소를 지원합니다. – CodeZombie

+0

부품을 사용하여 코드를 업데이트하십시오 – Tomtom

+1

로직을 뒤집을 필요가 있습니다. CancellationPending은 처음에는 false이며 사용자가 취소하려고 할 때 true가됩니다. 그래서 루프는'! worker.CancellationPending'을 확인해야합니다. – Chris

-2

처럼 보일 수있는 방법입니다. 무한 루프에서 실행해야하는 이유에 대해서는 언급하지 않았지만 Thread.Sleep을 루프에 넣기 시작하면됩니다.

+1

Thread.Sleep은 실천이 아니므로 생산에 투입해서는 안됩니다. 문제는 아마도 while while (true) 같은 루프가 진행되는 동안 다른 것으로 보입니다. 스레딩은 장기 실행 작업을 실행하고 종료 할 때 사용해야합니다. 작업이 끝난 후에도 스레드가 계속 실행될 이유가 없습니다. 그들이 말하는 것처럼 자연스럽게 일어날 수 있도록해야합니다. –

+0

@Ahmedilyas - 제작에 무엇이든 제안하지 않았습니다. 무한 루프를 실행하는 BackgroundWorker는 의문의 여지가 있지만 Thread.Sleep을 넣으면 OP가 "응용 프 로그 래밍"문제를 넘어서고 자신의 디자인에 대해 더 많이 생각할 수있는 위치에있게됩니다. 그는 무한 루프를 원하는 이유를 말하지 않았으므로 어떤 대안이 더 적절할지 제안하는 것은 어렵습니다. – Joe

+0

'무한 루프'는 일반적으로 멀티 스레드 응용 프로그램에서 CPU 사용이 100 %라는 것을 의미하지 않습니다. 일반적으로 스레드는 무언가를 차단합니다. 또한, Thread.Sleep의 이러한 사용은 실제로 나쁜 습관이지만 합법적 인 용도가 있습니다. –

4

백그라운드에서 실행할 항목이 필요할 때 이전에이 작업을 수행했습니다. 백그라운드 워커가 실행되는 동안 실행하려고하면, 당신은 대피 할 것입니다! 그래서 BackGroundWorker가 완료된 이벤트에서 완료 될 때 자체를 시작하게 만듭니다.

그리고 나서 영원히 반복됩니다.

private void Main_Load(object sender, EventArgs e) 
{ 
    // Start Background Worker on load 
    bgWorker.RunWorkerAsync(); 
} 

private void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Thread.Sleep(1000); // If you need to make a pause between runs 
    // Do work here 
} 

private void bgCheck_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
// Update UI 

// Run again 
bgWorker.RunWorkerAsync(); // This will make the BgWorker run again, and never runs before it is completed. 
} 
+1

끝내는 시간이 끝나기 전에 시작하는 대신, while (true) 루프가 없어도 무한대로 실행되는 이유는 무엇입니까? – bkribbs

+2

흠 잡을 데없이 일했습니다! 구현은 타이머보다 쉬우 며 UI를 잠그지 않고 작업을 수행합니다! 고마워, 좋은 방법 :)! 대답으로 표시해야합니다. –

+0

--bkribs이 방법으로 UI 요소를 업데이트해야하는 경우 "ProgressUpdated"및 "WorkerCompleted"에 코드를 추가 할 수도 있습니다. –

-1
timer.interval=60000 // 1 min 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     timer1.Start(); 

    } 
private void timer1_Tick(object sender, EventArgs e) 
    { 
     try 
     { 
      //Do something 
     } 
     catch 
     { 


     } 
    } 
+0

그냥 대답 대신 왜 대답이 작동하는지에 대한 세부 묘사 또는 설명을 포함시키는 것이 항상 좋은 생각입니다 암호. –

+1

이 코드 단편은 질문을 해결할 수 있지만 [설명 포함] (// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) 정말 게시물의 품질을 향상시키는 데 도움이됩니다. 앞으로 독자의 질문에 답하고 있으며 코드 제안의 이유를 알지 못할 수도 있습니다. 코드와 설명의 가독성을 떨어 뜨리기 때문에 주석을 설명하는 코드를 사용하지 마십시오! – FrankerZ