Необработанная ошибка исключения из обратного вызова c # - PullRequest
7 голосов
/ 12 декабря 2010

У меня трехуровневая архитектура, и я отправляю некоторые данные на транспортном уровне (TCP-клиент) с помощью сокетов tcp, если этот метод асинхронно использует метод BeginSend.

public void TransportData(Stream stream)
{
    try
    {
        SetTransporterState(StateObject.State.SendingData);
        if (clientSock.Connected)
        {
            ASCIIEncoding asen = new ASCIIEncoding();
            stream.Position = 0;
            byte[] ba = GetStreamAsByteArray(stream);
           if (clientSock.Connected)
              clientSock.BeginSend(ba, 0, ba.Length, SocketFlags.None, new AyncCallback(SendData), clientSock);
           else
               throw new SockCommunicationException("Socket communication failed");

         }
         catch (SocketException sex)
         {
             throw sex;
         }
         catch (SockCommunicationException comex)
         {
             bool rethrow = ExceptionPolicy.HandleException(comex, "TransportLayerPolicy");
         if (rethrow)
         {
             throw;
         }
       }
     }
   }
   catch (SocketException soex)
   {
     throw soex;
   }
   catch (SockCommunicationException comex)
   {
      bool rethrow = ExceptionPolicy.HandleException(comex, "TransportLayerPolicy");
      if (rethrow)
      {
         throw;
      }                
    }
    catch (Exception ex)
    {
       LoggingMessageHelper.LogDeveloperMessage(ex.Message + Environment.NewLine + ex.StackTrace, 1, TraceEventType.Critical);
        bool rethrow = ExceptionPolicy.HandleException(ex, "TransportLayerPolicy");
        if (rethrow)
        {
          throw;
        }
     }
  }

Код обратного вызова SendData () приведен ниже1004 *

    private void SendData(IAsyncResult iar)
    {
        Socket remote = null;
        try
        {
            remote = (Socket)iar.AsyncState;
            try
            {
                int sent = remote.EndSend(iar);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            if (remote.Connected )
            {
                remote.BeginReceive(data, 0, size, SocketFlags.None,
                              new AsyncCallback(ReceiveData), remote); 
            }
            else
                throw new SockCommunicationException("Communication Failed");
        }
        catch (SocketException soex)
        {
            throw new SockCommunicationException("Communication Failed");
        }
        catch (SockCommunicationException comex)
        {
            bool rethrow = ExceptionPolicy.HandleException(comex, "TransportLayerPolicy");
            if (rethrow)
            {
                throw;
            }
        }

Когда сервер отключается, клиент не знает, пока не отправит некоторые данные, поэтому свойство Connected имеет значение true.Затем строка remote.BeginReceive () генерирует исключение SocketException, которое я пытаюсь перехватить, и выбрасывает пользовательское исключение (sockCommunicationException).

Однако, когда я делаю это, я получаю необработанное исключение.Я хотел бы передать эту ошибку пользовательскому интерфейсу через бизнес-уровень.Когда подобное исключение вызывается в методе обратного вызова, где оно поднимается до?

Как можно избежать этого необработанного исключения и передать это исключение на уровень пользовательского интерфейса.

Пожалуйста, помогите.

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 12 декабря 2010

Да, не работает.Обратный вызов выполняется в потоке потоков, там некому перехватить исключение.Вам нужно, скажем, вызвать событие, на которое пользовательский интерфейс может подписаться.Требуется маршалинг, код пользовательского интерфейса должен использовать что-то вроде Control.BeginInvoke (), если ему нужно обновить интерфейс.

2 голосов
/ 12 декабря 2010

Это общее требование.

Решение обычно заключается в SendData, имеющем доступ к некоторому локальному методу , чтобы уведомить клиента о результате операции и, возможно, отобразить в пользовательском интерфейсе..

Теперь вам нужно достичь этого в среднего уровня , который отличается .Ваш клиент вызывает сервер, который, в свою очередь, вызывает асинхронный метод и запускает операцию.Если клиент должен знать о результате и его исключениях, он должен опросить сервер и проверить результат - и вам нужно будет сохранить результат (на сервере или в какой-либо базе данных), пока клиент не получитэто или выбросить после тайм-аута - сама очистка становится сложной.

В качестве альтернативы он мог бы использовать метод Duplex , чтобы сервер мог связаться с клиентом.Это решение звучит замечательно, но быть справедливым - это ужасно по различным причинам, которые выходят за рамки этого вопроса.

...