TIdTCPServer 的 TIdContext->Data 异常行为
TIdTCPServer's TIdContext->Data odd behaviour
为了向多个客户端发送数据,我在 OnConnect
中创建了一个 TIdThreadSafeStringList
并将其分配给 AContext->Data
,就像这样
AContext->Data = new TIdThreadSafeStringList
当客户端断开连接时,它的字符串列表在OnDisconnect
中被删除,就像这样
delete AContext->Data
但是这会产生 AV。如果我将参数归零,就像这样
delete AContext->Data
AContext->Data = NULL
AV 消失了。是否有一些我不知道的自动清理?
使用 C++ Builder 10.2.3.
Is there some auto cleanup I'm not aware of?
是的。 TIdContext
派生自 TIdTask
,后者拥有 Data
属性。 TIdTask
析构函数在 OnDisconnect
事件之后调用,如果 Data
对象不是 NULL
.
,则将释放该对象
处理这种情况的另一种(首选)方法是从 TIdServerContext
派生一个新的 class 并将您的 TIdThreadSafeStringList
添加到 class (以及任何其他您想要的每个客户端自定义功能),例如:
class TMyContext : public TIdServerContext
{
public:
TIdThreadSafeStringList *MyList;
__fastcall TMyContext(TIdTCPConnection *AConnection, TIdYarn *AYarn, TIdContextThreadList *AList = NULL)
: TIdServerContext(AConnection, AYarn, AList)
{
MyList = new TIdThreadSafeStringList;
}
__fastcall ~TMyContext()
{
delete MyList;
}
//...
};
然后在激活服务器之前在运行时将你的class类型分配给服务器的ContextClass
属性,例如:
__fastcall TMyForm::TMyForm(TComponent *Owner)
: TForm(Owner)
{
IdTCPServer1->ContextClass = __classid(TMyContext);
//...
}
然后,您可以简单地将属于服务器的任何 TIdContext*
指针类型转换为您的 class 类型,以便访问 TIdThreadSafeStringList
(或其他功能):
static_cast<TMyContext*>(SomeIdContext)->MyList->...
这样,您可以完全忽略 TIdContext::Data
属性,或者根据需要将其用于其他目的。
为了向多个客户端发送数据,我在 OnConnect
中创建了一个 TIdThreadSafeStringList
并将其分配给 AContext->Data
,就像这样
AContext->Data = new TIdThreadSafeStringList
当客户端断开连接时,它的字符串列表在OnDisconnect
中被删除,就像这样
delete AContext->Data
但是这会产生 AV。如果我将参数归零,就像这样
delete AContext->Data
AContext->Data = NULL
AV 消失了。是否有一些我不知道的自动清理?
使用 C++ Builder 10.2.3.
Is there some auto cleanup I'm not aware of?
是的。 TIdContext
派生自 TIdTask
,后者拥有 Data
属性。 TIdTask
析构函数在 OnDisconnect
事件之后调用,如果 Data
对象不是 NULL
.
处理这种情况的另一种(首选)方法是从 TIdServerContext
派生一个新的 class 并将您的 TIdThreadSafeStringList
添加到 class (以及任何其他您想要的每个客户端自定义功能),例如:
class TMyContext : public TIdServerContext
{
public:
TIdThreadSafeStringList *MyList;
__fastcall TMyContext(TIdTCPConnection *AConnection, TIdYarn *AYarn, TIdContextThreadList *AList = NULL)
: TIdServerContext(AConnection, AYarn, AList)
{
MyList = new TIdThreadSafeStringList;
}
__fastcall ~TMyContext()
{
delete MyList;
}
//...
};
然后在激活服务器之前在运行时将你的class类型分配给服务器的ContextClass
属性,例如:
__fastcall TMyForm::TMyForm(TComponent *Owner)
: TForm(Owner)
{
IdTCPServer1->ContextClass = __classid(TMyContext);
//...
}
然后,您可以简单地将属于服务器的任何 TIdContext*
指针类型转换为您的 class 类型,以便访问 TIdThreadSafeStringList
(或其他功能):
static_cast<TMyContext*>(SomeIdContext)->MyList->...
这样,您可以完全忽略 TIdContext::Data
属性,或者根据需要将其用于其他目的。