2010-02-08 3 views
4

저희 회사는 GUI 응용 프로그램 용 네트워크 구성 요소 (DLL)를 제공합니다.이 SocketException이 일반 catch 루틴에 의해 포착되지 않는 이유는 무엇입니까?

연결 끊김을 확인하는 타이머를 사용합니다. 그것은 다시 연결하고자하는 경우, 전화 :

internal void timClock_TimerCallback(object state) 
{ 
    lock (someLock) 
    { 
    // ... 
    try 
    { 
     DoConnect(); 
    } 
    catch (Exception e) 
    { 
     // Log e.Message omitted 
     // Raise event with e as parameter 
     ErrorEvent(this, new ErrorEventArgs(e)); 
     DoDisconnect(); 
    } 
    // ... 
    } 
} 

그래서 문제가 SocketException이 슬로우 (그리고 잡힌되지 않음)하는 DoConnect() 루틴의 내부입니다. catch (Exception e)는 모든 예외를 catch해야하지만 SocketException은 잡히지 않아 GUI 응용 프로그램에 표시된다고 가정합니다.

protected void DoConnect() 
{ 
    // 
    client = new TcpClient(); 
    client.NoDelay = true; 
    // In the following call the SocketException is thrown 
    client.Connect(endPoint.Address.ToString(), endPoint.Port); 
    // ... (login stuff) 
} 

doc은 SocketException이 Exception을 확장한다는 것을 확인했습니다. 나타났다 스택 트레이스는 다음과 같습니다

TcpClient.Connect() -> DoConnect() -> timClock_TimerCallback 

는 그래서 예외는 try/catch 블록 외부에서 발생하지 않습니다.

왜 작동하지 않는가?

+0

디버거가 연결되어 있거나 항상 코드가 실행 중일 때만이 문제가 발생합니까? 또한 catch 블록은 try 블록의 모든 예외를 catch하도록 보장되지만 DoConnect가 화재를 처리하고 예외를 발생시키는 것을 잊어 버리면 DoConnect가 반환되고 처리가 계속되어 의도 한 처리기에서 처리되지 않은 예외가 발생합니다. – cfeduke

답변

0

약간의 프로그램을 작성하고 재현 할 수 없기 때문에 TimerCallback 내부에서 SocketException이 발견되었습니다.

분석을 다시 생각해보십시오. 문제는 생각했던 것과 다를 수 있습니다. 몇 가지 제안 :

  • 타이머 외부에서 실행하십시오. T | hat은 쓰레딩을 루프에서 제거합니다.
  • 디버거에서 실행하십시오. 예외는 실제로 어디에서 발생합니까?
  • 예외 처리 단계. ErrorEvent가 수행해야하는 작업은 무엇입니까?
+0

고맙습니다. 왜 이런 일이 일어 났으며 새로운 영감을 원했는지에 대한 설명이 없었기 때문에 질문을했습니다. 나는 그것이 재현 가능하다고 생각하지 않는다. (분명히 당신의 프로그램이 보여준 것처럼)하지만 분명히 일어 났으므로 조사해야했다 .. – Tarnschaf

+0

동작은 여전히 ​​재현 할 수 없다. 그래서 나는 디버그 코드를 추가했고 그것이 다시 발생하면 기다릴 것이다. 가장 쉽기 때문에 대답을 수락하십시오. – Tarnschaf

1

ErrorEvent이 정말로 (덧글 당) 다른 예외를 발생시키는 경우 DoDisconnect()은 절대로 실행되지 않습니다.

그렇지 않으면, 당신이 볼 수있는 예외는 당신이 DoConnect() 코드를 게시 할 수있는 형태로 DoDisconnect()

+0

추가 된 stacktrace가 해결책이 될 수없는 이유를 확인하십시오. – Tarnschaf

0

올 수 있는가?

시도 할 항목 : DoConnect()에서이 잡을 수 있습니까? 제네릭 대신 특정 예외를 포착 해보십시오. 디버그 모드를 사용하면 어떻게 반응합니까?

+0

다른 사람들에게 남긴 답장을 읽으면서 코드를 그대로두고 두 번째 catch 블록을 추가하여 SocketExeption 또는 Win32Exception을 잡습니다. – Roast

+0

은 요청에 따라 DoConnect() 메서드를 추가했습니다. SocketException이 Win32Exception을 확장 할 때 아이디어에 대한 설명도 있습니까? extends Exception Exception? – Tarnschaf

+0

두 가지 이유가 있습니다. .NET 1.1 win32exception이 Exception에서 파생되지 않았습니다. 그렇지 않으면 DoConnect 내부에서 시작된 다른 스레드에서 Throw되기 때문에 예외가 잡힐 가능성이 없습니다. – Roast

0

귀하의 timClock_TimerCallback은 catch-statement가 예외를 잡으려고하는 동일한 스레드에서 호출되지 않습니다. timClock_TimerCallback 안에 예외를 catch 한 다음 자체를 호출 한 다음 올바른 스레드에서 예외를 다시 발생시키는 메서드를 호출해야합니다.

잘 될지 모르지만 시도해 볼 수 있습니다.

+1

그 흥미로운 것 ..하지만 TcpClient.Connect() 또한 catch가 상주하는 TimerCallback 스레드에서 호출됩니다, 다른 스레드가 관련 될 수 있을까? – Tarnschaf

+0

죄송합니다. timClock_TimerCallback이 어떻게 든 DoConnect에서 호출되었지만 분명히 잘못되었습니다. 내 대답이 너를 도와주지 않을까 봐 걱정된다. –

관련 문제