2012-09-21 4 views
5

주 UI 스레드와 4 개의 작업으로 구성된 WinForms 응용 프로그램이 있습니다. 내 기본 양식이 같은 개인 회원 레벨 변수가 있습니다) (내 DoStuff의 각각의 내부실행중인 작업이있는 닫는 양식

keepThreadsRunning = true; 
var task1Worker = Task.Factory.StartNew(() => DoStuff1()); 
var task2Worker = Task.Factory.StartNew(() => DoStuff2()); 
var task3Worker = Task.Factory.StartNew(() => DoStuff3()); 
var task4Worker = Task.Factory.StartNew(() => DoStuff4()); 

: 내 기본 폼의 Load() 이벤트에서

private bool keepThreadsRunning = false; 

을, 나는 다음과 같은이 방법, 기본적으로 내가이 있습니다

while (keepThreadsRunning) 
{ 
    // do work here 
    Thread.Sleep(30000); // a couple of my tasks only need to run every 30 seconds or so 
} 

마지막으로, 내 Form_Closing() 이벤트 핸들러에서, 나는 다음과 같습니다

keepThreadsRunning = false; 
this.Close(); 

작업 관리자에서 내 응용 프로그램을보고 내 양식을 닫을 때 프로세스가 끝났지 만 4 가지 작업에 대해서는 약간 혼란스러워 보입니다. this.Close()에 대한 호출이 실제로 해당 작업을 종료하게합니다 (Thread.Sleep() 호출이 발생하더라도). 그리고 지금 코딩하는 방식보다 더 좋은 방법이 있습니까?

EDIT - 앱을 종료 할 때 잠깐 살펴 봤지만 내 작업에서 취소 토큰을 주기적으로 확인하여 취소되었는지 확인해야합니다. 일부 작업이 매 30 초마다 실행되어야한다는 것을 감안할 때 30 초 대기 (현재 Thread.Sleep())를 구현하는 방법을 파악할 수 없으며 작업에 취소 토큰을 확인해야합니다. WaitHandle이 설정 될 때까지

do { 
    // do work here 
} while (!threadTerminationHandle.WaitOne(TimeSpan.FromSeconds(30)) 

이 대기 : 스레드에서

var threadTerminationHandle = new ManualResetEvent(false); 

:

답변

2

먼저 다른 작업을 종료합니다 메인 UI 스레드를 폐쇄. 계속 실행해야하는 경우 별도의 콘솔 응용 프로그램 또는 Windows 서비스에서 실행하는 것이 좋습니다.

실행해야하는 메소드 실행을 마친 동안 양식 닫는 것을 지연시키는 방법을 찾았더라도, 최종 사용자가 원하는 방식으로 양식을 닫은 경우에만 작동하며, Windows는 Windows가됩니다 응용 프로그램을 종료하는 백만 가지 방법 중 하나이므로이 방법이 작동한다는 보장은 없습니다.

는 방법을 초 비동기 적으로 모든 X 금액을 실행하는 경우, 당신은과 같이, 모든 일에 대한 타이머를 사용할 수 있습니다

using System; 
using System.Timers; 
using System.Windows.Forms; 

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      var timer1 = new System.Timers.Timer { Interval = 30000, Enabled = true }; 
      var timer2 = new System.Timers.Timer { Interval = 20000, Enabled = true }; 
      var timer3 = new System.Timers.Timer { Interval = 10000, Enabled = true }; 
      var timer4 = new System.Timers.Timer { Interval = 5000, Enabled = true }; 

      timer1.Elapsed += timer1_Elapsed; 
      timer2.Elapsed += timer2_Elapsed; 
      timer3.Elapsed += timer3_Elapsed; 
      timer4.Elapsed += timer4_Elapsed; 
     } 

     void timer4_Elapsed(object sender, ElapsedEventArgs e) 
     { 
      //do work here 
     } 

     void timer3_Elapsed(object sender, ElapsedEventArgs e) 
     { 
      //do work here 
     } 

     void timer2_Elapsed(object sender, ElapsedEventArgs e) 
     { 
      //do work here 
     } 

     void timer1_Elapsed(object sender, ElapsedEventArgs e) 
     { 
      //do work here 
     } 
    } 
} 
3

오히려 부울 및 Thread.Sleep()을 사용하는 것보다, 같이 만들어 구체적으로 WaitHandle하는 ManualResetEvent를 사용 , 또는 30 초가 경과하면 더 빠른 날짜가됩니다. 양식에서

: 모든

threadTerminationHandle.Set(); 
Close(); 
2

는 가까운 응용 프로그램, 작업 그에 따라 폐쇄 될 때 작업이 처리되기 때문에 배경 스레드에서 스레드 풀. 따라서 취소 토큰을 주기적으로 확인하여 취소 여부를 확인할 필요가 없습니다.

관련 문제