使用RHTTPTransaction后产生CONE 36 Panic的解决办法

来源:互联网 发布:神探夏洛克第五季 知乎 编辑:程序博客网 时间:2024/06/08 19:34

当应用程序只使用RHTTPSessionRHTTPTransaction来进行HTTP操作,那么在模拟器上的程序退出后会产生CONE 36panic,通过SDK可以找到对应的说明“Open handles were found during application shutdown”也就是说程序在退出时还有系统资源没有释放(R类),那么产生问题原因是什么呢?

分析程序的整个流程可以发现:应用程序首先通过RHTTPTransaction::SubmitL()提交第一次请求后系统会弹出接入点选择的对话框,在我们选择一个接入点后系统开始我们的应用建立网络的初始连接,其实这个过程就是通过RConnection::Start()来完成的,连接建立成功后把它和应用程序进行关联,而我们的程序在退出时并没有显示地通过RConnection::Close()来关闭连接,这就造成了资源没被释放从而产生了CONE 36这个panic。解决办法有两个:一、我们的程序自己通过RConnection创建连接,然后在程序退出时会关闭它:

class CHTTPEngine :     public CBase,

                                          public MHTTPTransactionCallback,

                                          public MHTTPDataSupplier,

                                          public MHTTPAuthenticationCallback

{

 .......................

 private:

 .......................

 RSocketServ        iSocketServ;

 RConnection        iConnection;

 RHTTPSession            iSession;

 RHTTPTransaction      iTransaction;

}

//为了方便代码演示使用了同步连接操作.

void CHTTPEngine::ConnectL()

{

       iSocketServ.Connect();

      iConnection.Open(iSocketServ);

 

     iConnection.Start();

      User::WaitForRequest( status );   //wait for connecting

       User::LeaveIfError( status.Int() );

      

       iSession.OpenL()

      

       RHTTPConnectionInfo connInfo = iSession.ConnectionInfo();

       RStringPool pool = iSession.StringPool();

 

       //HTTP会话设置连接

       connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketServ,RHTTPSession::GetTable()), THTTPHdrVal(iSocketServ.Handle()));

 

       TInt connPtr = REINTERPRET_CAST(TInt, &iConnection);

       connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketConnection,RHTTPSession::GetTable()), THTTPHdrVal(connPtr));

}

 

CHTTPEngine::~CHTTPEngine()

{

      ........................

 

       iConnection.Close();

       iSocketServ.Close();

       iSession.Close();

       ....................

}

 

二、不使用额外的RSocketServRConnection,在退出时获取相关联的对象,然后关闭连接:

CHTTPEngine::~CHTTPEngine()

{

       RHTTPConnectionInfo connInfo = iSession.ConnectionInfo();

       RStringPool pool = iSession.StringPool();

 

       //HTTP会话设置连接的反向操作

       THTTPHdrVal val;

       TBool ret = connInfo.Property(pool.StringF(HTTP::EHttpSocketServ,RHTTPSession::GetTable()), val  );

 

       RSocketServ socketServ;

       RConnection *connection = NULL;

       if( ret )

       {

              socketServ.SetHandle( val.Int() );

              ret = connInfo.Property(pool.StringF(HTTP::EHttpSocketConnection,RHTTPSession::GetTable()), val );

 

              if( ret )

              {

                     connection = REINTERPRET_CAST(RConnection*, val.Int());

              }

              if( connection )

              {

                     connection->Close();

              }

 

              socketServ.Close();

       }

 

       iSession.Close();

      

....................

}

 

第一种方法自己建立连接,通常使用异步机制,增加了程序的复杂度,但是可以通过RConnection::Start()的另一个版本Start(TConnPref& aPref, TRequestStatus& aStatus)实现隐藏接入点选择对话框,自己设置接入点。第二种方法不用添加额外的操作,适合不关心接入点的应用。

原创粉丝点击