Почему это исключение SocketException не перехватывается обычной процедурой перехвата? - PullRequest
4 голосов
/ 08 февраля 2010

Наша компания предоставляет сетевой компонент (DLL) для приложения с графическим интерфейсом.

Используется таймер, который проверяет наличие отключений. Если он хочет восстановить соединение, он вызывает:

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();
    }
    // ...
  }
}

Таким образом, проблема в том, что внутри подпрограммы DoConnect () создается исключение SocketException (и не перехватывается). Я бы предположил, что catch (Exception e) должен перехватывать ВСЕ исключения, но каким-то образом SocketException не был перехвачен и отображается в приложении с графическим интерфейсом.

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)
}

Документ подтвердил, что SocketException расширяет Exception. Появился след стека:

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

Таким образом, исключение не выдается за пределами блока try / catch.

Есть идеи, почему это не работает?

Ответы [ 4 ]

1 голос
/ 08 февраля 2010

Если ErrorEvent действительно вызывает другое исключение (согласно комментарию), то DoDisconnect() никогда не выполняется.

В противном случае вы увидите, что исключение может появиться из DoDisconnect()

0 голосов
/ 08 февраля 2010

Я написал небольшую программу и не смог воспроизвести, SocketException был пойман внутри TimerCallback просто отлично.

Поэтому я предлагаю вам переосмыслить свой анализ, проблема может быть не в том, что вы думаете. Несколько предложений:

  • запустить его вне таймера. T | hat убирает резьбу из цикла.
  • запустите его в отладчике. Где на самом деле происходит исключение?
  • шаг через обработку исключений. ErrorEvent делает то, что должен?
0 голосов
/ 08 февраля 2010

Ваш timClock_TimerCallback не вызывается в том же потоке, в котором оператор catch хочет перехватить исключение. Вы должны перехватить исключение внутри timClock_TimerCallback, а затем вызвать метод, который вызывает себя, а затем повторно выбросить исключение в нужном потоке.

Не уверен, что это сработает, но вы можете попробовать.

0 голосов
/ 08 февраля 2010

Не могли бы вы опубликовать код DoConnect ()?

Также стоит попробовать: Можете ли вы поймать его в DoConnect ()? Попробуйте поймать конкретное исключение вместо общего. Как это отреагирует, если вы используете режим отладки?

...