2013-05-03 2 views
0

이 작은 프로그램을 단계별로 F10 단추로 디버깅 할 때 프로그램은 timer.Elapsed += 수준에 도달 할 때까지 합리적입니다. 이 후 내 방법 Check(MyConn)을 호출해야하지만 그것은하지 않습니다! 그것은 MyConn.Close();으로 돌아가고이 둘 사이에서 튀어 오릅니다, 그리고 갑자기 프로그램이 닫힙니다!C에서 메서드 및 타이머

어디에서 문제가 발생했는지 궁금합니다.이 줄에서 올 수 있을까요? timer.Elapsed += (timerSender, timerEvent) => timer_Elapsed(timerSender, timerEvent, MyConn);? 이 포럼에 게시 된 해결책은 다음과 같습니다. MyConntimer_Elapsed ...

도움을 주셔서 감사합니다.

static void Main(string[] args) 
{ 
    // create connection 
    string ConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\mike\\Documents\\Database1.mdb;"; 

    OleDbConnection MyConn = new OleDbConnection(ConnStr); 
    MyConn.Open(); 

    initTimer(MyConn); 

    MyConn.Close(); 
} 

static void initTimer(OleDbConnection MyConn) 
{ 
    //set up a timer 
    Timer timer = new Timer(); 
    timer.Interval = 2000; // check every 2s (2000ms) if the values in the database changed 
    timer.Enabled = true; //enable the timer, so when the timer elapses after 2s, it performs some calculations 

    timer.Elapsed += (timerSender, timerEvent) => timer_Elapsed(timerSender, timerEvent, MyConn); 
} 

static void timer_Elapsed(object sender, ElapsedEventArgs e, OleDbConnection MyConn) 
{ 
    Check(MyConn); // Check is a method I have in my program which takes as argument "MyConn" 
} 
+1

몇 가지 - 예외는 무엇입니까? 'Check'는'MyConn' 객체와 무엇을합니까? 왜냐하면 당신은 타이머를 사용할 기회가 있기 전에 즉시 연결을 닫을 것이기 때문입니다. – James

답변

2

타이머를 설정하면 코드가 계속 실행됩니다. initTimer 메서드를 그대로두고 연결을 닫습니다. 그런 다음 Main 함수가 종료되어 응용 프로그램이 닫힙니다. 또한 타이머가 종료됩니다.

프로그램이 종료되지 않는 경우 타이머는 2000부터 카운트 다운됩니다. 0에 도달하면 타이머가 이벤트를 시작합니다. 이것은 다른 스레드에서 발생하며 주 극장과 병렬로 발생합니다. 귀하는 심지어 연결을 점검 할 것입니다. 연결은 까다롭게 닫힙니다.

이벤트가 발생할 때까지 주요 위협 요소를 기다리고 싶다면 왜 타이머를 사용해야합니까? 왜 안되니?

static void Main(string[] args) 
{ 
    // create connection 
    string ConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\mike\\Documents\\Database1.mdb;"; 

    using(OleDbConnection MyConn = new OleDbConnection(ConnStr)) 
    { 
     MyConn.Open(); 
     do 
     { 
      Thread.Sleep(2000); 
      Check(MyConn); 
     } 
     while(someValueToIndicateTheApplicationCanTerminate); 
    } 
} 
+0

이벤트가 다른 스레드에 있다는 것을 알지 못했습니다. 이제는 같은 시간에 실행되기 때문에 이해가됩니다. 내가 원한 것은 매번 "Check (MyConn)"메소드를 실행하는 데 걸리는 시간 (예 : 2 초)입니다. 당신이 썼던 방식으로, 당신은 "Thread.Sleep (3000)"을 넣었습니다. 그것은 주 스레드가 3 초 동안 잠을 자도록 함을 의미합니까 ?? 그렇다면 연결을 종료했기 때문에 "Check (MyConn)"메서드를 실행하는 방법을 알 수 없습니다. – Mike

+0

예. 'Thread.Sleep (3000)'은 3 초를 기다리는 것을 의미합니다. 나는 당신의'수표'가 무엇을 검사하고 있는지 알지 못했습니다. 연결이 열려 있는지 확인 했습니까? 아니면 뭔가 다른 생각은? 물론 연결을 닫는 코드 앞에 지연 코드를 옮길 수 있습니다. –

+0

귀하의 요청에 대한 답변을 업데이트했습니다. –

3

이것은 정상적인 동작입니다.

timer.Elapsed += 코드는 이벤트 만 등록 중입니다. 2 초 후 이벤트가 발생하지만 주 스레드는 정상적으로 계속 진행되어 Main() 기능으로 돌아갑니다. 그런 다음 MyConn.Close()을 호출 한 다음 Main() 함수를 끝냅니다.

콘솔 응용 프로그램 인 경우 프로그램이 끝날 것이므로 timer_Elapsed 이벤트가 실행될 시간이 없음을 의미합니다.

서비스 또는 양식 응용 프로그램처럼 "생존"할 응용 프로그램 인 경우 timer_Elapsed 이벤트가 발생하기 전에는 연결이 이미 닫혀있을 것입니다.


당신이 "살아 남기"응용 프로그램이있는 경우 그때 당신이 실제로 사용한다 함수에 열기/닫기 연결 코드를 이동해야합니다, 제안합니다. 이 경우에는 timer_Elapsed 이벤트 안에 있습니다.

"살아있는 앱"이 없다면 아마 타이머와 별도의 스레드가있는 모든 것을 피해야합니다.

덧붙여서, 나는 계속 「살아있어 라」라고 말하고 있습니다. 나는 그것이 무엇을 의미하는지 알고 있기를 바랍니다. 나는 그것을 기술하는 더 전문 용어를 모른다.

+0

사실 콘솔 응용 프로그램이 있습니다. 고마워, 이제 스레드 동작을 이해합니다. 그러나 예를 들어 "Check (MyConn)"메소드를 원한다면 어떻게 해결할 수 있습니까? 메인 랩의 스레드를 잠시 동안 두 번씩 (내 예제에서는 2 초) 실행합니다. – Mike

+0

@Mike :'Main' 함수에서 while 루프를 사용할 수 있습니다.이 함수는 각 루프를 잠자 게합니다. 무한대가되는 것을 피하려면 각 루프를 종료해야하는지 확인하는 것이 좋습니다. 이 플래그를 설정하는 방법은 전체적으로 무엇을하고 있는지에 달려 있습니다. – musefan

+0

자동 검사를하고 싶습니다. 내 방법을 원합니다. 매 2 초마다 무한대로 실행하도록 확인하십시오. 이것은 주 모니터를 닫을 수 없다는 것을 전제로합니다. , 아니? 타이머 이벤트가 메서드를 실행하는 동안 주 스레드가 연결을 닫지 않기를 원합니다. 확인 ...이 작업을 수행하려고합니다! – Mike

관련 문제