简体   繁体   English

回调c#中未处理的异常错误

[英]Unhandled Exception error from a callback c#

I have a 3 tier architecture and send some data in the transport layer (TCP Client) using tcp sockets is this methods asynchronously using BeginSend method. 我有一个3层架构并使用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;
        }
     }
  }

The callback code SendData() is below 回调代码SendData()如下所示

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

When the server disconnects, the client does not know until it sends some data, therefore the Connected property is true. 当服务器断开连接时,客户端在发送一些数据之前不知道,因此Connected属性为true。 Then the line remote.BeginReceive() throws the SocketException which I try to capture and throw a custom exception (sockCommunicationException). 然后行remote.BeginReceive()抛出我试图捕获的SocketException并抛出一个自定义异常(sockCommunicationException)。

However when I do this I get an unhandled exception. 但是,当我这样做时,我得到一个未处理的异常。 I would like to bubble this error to the UI through the Business layer. 我想通过业务层将此错误冒泡到UI。 When an exception like this is raised in the callback method, where does it get raised to? 当在回调方法中引发这样的异常时,它会被提升到哪里?

How can I avoid this undhandled exception and bubble this exception to the UI layer. 如何避免此未处理的异常并将此异常冒泡到UI层。

Please help. 请帮忙。

Thanks in advance! 提前致谢!

Yes, doesn't work. 是的,不起作用。 The callback is executed on a threadpool thread, there's nobody there to catch the exception. 回调是在线程池线程上执行的,没有人可以捕获异常。 You'll need to, say, raise an event that the UI can subscribe to. 例如,您需要引发UI可以订阅的事件。 Marshaling is required, the UI code needs to use something like Control.BeginInvoke() if it needs to update the UI. 编组是必需的,如果需要更新UI,UI代码需要使用类似Control.BeginInvoke()的东西。

This is a common requirement. 这是一个常见的要求。

Solution is usually by SendData having access to some local method to notify the client of the result of the operation and possibly showing in the UI. 解决方案通常是SendData可以访问某些本地方法来通知客户端操作的结果并可能在UI中显示。

Now you need to achieve this in the middle-tier which is different . 现在,你需要在中间层不同的 ,以实现这一目标。 Your client calls the server which in turn calls async method and triggers the operation. 您的客户端调用服务器,服务器又调用异步方法并触发操作。 If the client needs to know about the result and its exceptions, it has to poll the server and check for the result - and you would have to store the result (on the server or some database) until client retrieves it or throw away after a time-out - cleanup itself becomes complex. 如果客户端需要知道结果及其异常,则必须轮询服务器并检查结果 - 并且您必须将结果存储(在服务器或某个数据库上),直到客户端检索它或在超时 - 清理本身变得复杂。

Alternatively it could use a Duplex method for the Server to communicate back to the Client. 或者,它可以使用Duplex方法将服务器与客户端进行通信。 This solution sounds great but to be fair is awful for various reasons which is outside the scope of this question. 这个解决方案听起来不错,但公平对于各种原因都是可怕的 ,这超出了本问题的范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM