2010-12-12 39 views
7

我有一个3层体系结构并使用tcp套接字发送传输层(TCP客户端)中的一些数据,这种方法是使用BeginSend方法异步执行的。来自回调的未处理异常错误c#

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

回调代码送出数据()低于

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()一行将引发我试图捕获并抛出一个自定义异常(sockCommunicationException)的SocketException。

但是,当我这样做,我得到一个未处理的异常。我想通过业务层将此错误发布到UI。当在回调方法中引发这样的异常时,它会引发什么?

我该如何避免这种未处理的异常并将此异常冒泡到UI层。

请帮忙。

在此先感谢!

回答

2

这是一个常见的要求。

解决方案通常由SendData访问某些本地方法来通知客户端操作的结果并可能在UI中显示。

现在,您需要在中间层这是不同实现这一目标。您的客户呼叫服务器,该服务器又调用异步方法并触发该操作。如果客户需要知道结果及其例外情况,则必须轮询服务器并检查结果 - 并且必须将结果(在服务器或某个数据库上)存储起来,直到客户端检索结果或丢弃为止超时后 - 清理本身变得复杂。

或者,它可以使用双工方法让服务器与客户端进行通信。这个解决方案听起来不错,但公平的是可怕的由于各种原因,这是超出了这个问题的范围。

+0

嗨Aliostad,那么你是说我有一个委托在传输层,并提出一个由业务层订阅的事件,当这种错误发生? – user466898 2010-12-12 18:28:02

+0

不,我的首选方法是让客户端轮询服务器,看其**是否知道结果。 – Aliostad 2010-12-12 18:29:43

+0

我很抱歉,我没有得到。如果我之前没有清楚地解释它,客户端发送请求,服务器回复它已经断开客户端的错误。这就是为什么我得到socketexception的提示信息“建立的连接被主机中的软件中止”和错误代码“10053”。我只在回调方法中的remote.BeginReceive()行中引发此错误。我只需要向上泡泡。 – user466898 2010-12-12 18:38:28

3

是的,不起作用。回调是在一个线程池线程上执行的,没有人可以捕获异常。比如,你需要提出一个UI可以订阅的事件。编组是必需的,如果需要更新UI,UI代码需要使用类似Control.BeginInvoke()的东西。

+0

谢谢,我可以通过检查InvokeRequired并使用委托对其进行相应处理来处理UI。提出一个事件是将错误提示到业务层并从那里到用户界面的最佳方法? – user466898 2010-12-12 18:41:31

+1

对于异步错误,是的。 – 2010-12-12 18:43:36

+0

好的......再次感谢Hans !.我在想,如果在.NET框架中有一些内置的方法来处理这样的事情而不使用事件。 – user466898 2010-12-12 18:45:53