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 属性,或者根据需要将其用于其他目的。