Multithreading 正在丢失TThreadList的内容

Multithreading 正在丢失TThreadList的内容,multithreading,delphi,pascal,Multithreading,Delphi,Pascal,我遇到了一个问题,我的TThreadList的内容似乎在我的线程中丢失了 我在“PConnect”类中创建以下变量: 和一个全局变量,如下所示: var mCustomfunctionCallbackThreadList: TThreadList; function PConnect.callCustomfunction(plugin, method: PAnsiChar; param :CustomParam; callback: ICustomfunctionCallback; call

我遇到了一个问题,我的TThreadList的内容似乎在我的线程中丢失了

我在“PConnect”类中创建以下变量:

和一个全局变量,如下所示:

var mCustomfunctionCallbackThreadList: TThreadList; 
function PConnect.callCustomfunction(plugin, method: PAnsiChar; param :CustomParam; callback: ICustomfunctionCallback; callId: PAnsiChar): integer;
var paramName: PAnsiChar;
var id: PAnsiChar;
var error: integer;
var callbackList: TList;
var customfunctionCallback : ^CustomfunctionCallbackObject;
begin
     callbackList:= mCustomfunctionCallbackThreadList.LockList;

     new (customfunctionCallback);
     customfunctionCallback.callId:= id;
     customfunctionCallback.callbackMethod:= callback;
     callbackList.Add(customfunctionCallback);

     mCustomfunctionCallbackThreadList.UnlockList;
     exit(0);
end; 
现在我在“PConnect”类中填充这个变量,如下所示:

var mCustomfunctionCallbackThreadList: TThreadList; 
function PConnect.callCustomfunction(plugin, method: PAnsiChar; param :CustomParam; callback: ICustomfunctionCallback; callId: PAnsiChar): integer;
var paramName: PAnsiChar;
var id: PAnsiChar;
var error: integer;
var callbackList: TList;
var customfunctionCallback : ^CustomfunctionCallbackObject;
begin
     callbackList:= mCustomfunctionCallbackThreadList.LockList;

     new (customfunctionCallback);
     customfunctionCallback.callId:= id;
     customfunctionCallback.callbackMethod:= callback;
     callbackList.Add(customfunctionCallback);

     mCustomfunctionCallbackThreadList.UnlockList;
     exit(0);
end; 
在收到回调后,将调用以下函数。此函数应将其他缺少的数据附加到TThreadList条目,然后启动一个线程:

procedure PConnect.customfunctionCallbackReceived(param :CustomParam; callId: PAnsiChar; error: integer);
var customfunctionCallbackList: TList;
var it: TListEnumerator;
var callbackObject: ^CustomfunctionCallbackObject;
begin
    customfunctionCallbackList:= mCustomfunctionCallbackThreadList.LockList;
    it:= customfunctionCallbackList.GetEnumerator;
    while(it.MoveNext) do
    begin
        callbackObject:= it.GetCurrent;
        if strcomp(callbackObject.callId,callId) = 0 then
        begin
            callbackObject.param:= param;
            callbackObject.error:= error;
            break;
        end;
    end;
    mCustomfunctionCallbackThreadList.UnlockList;
    mCustomfunctionCallbackThread.Start();
end;  
线程的Execute方法应该获取TThreadList的内容,并使用该参数调用函数

procedure CustomfunctionCallbackThread.Execute;
var callback: ICustomfunctionCallback;
var customfunctionCallbackList: TList;
var it: TListEnumerator;
var callbackObject: ^CustomfunctionCallbackObject;
var param: CustomParam;
var callId: PAnsiChar;
var error: Integer;
begin
    customfunctionCallbackList:= mCustomfunctionCallbackThreadList.LockList;
    it:= customfunctionCallbackList.GetEnumerator;
    while(it.MoveNext) do
    begin
        callbackObject:= it.GetCurrent;
        if callbackObject.error <> NULL then
        begin
            callback:= callbackObject.callbackMethod;
            param:= callbackObject.param;
            error:= callbackObject.error;
            callId:= callbackObject.callId;

            callback.callCustomfunctionCallback(param, callId, error);
            customfunctionCallbackList.Remove(callbackObject);
            break;
        end;
    end;
    mCustomfunctionCallbackThreadList.UnlockList;
end; 
我希望描述得足够多:)

我很高兴能得到一些帮助:)

当你这样做的时候

customfunctionCallback.callId:= id
变量
id
尚未初始化。这意味着当你稍后检查时

strcomp(callbackObject.callId,callId) = 0
它的行为定义不清,因为
callbackObject.callId
从未初始化过。然后发生的情况是,您看到的定义不正确的行为是,表达式的计算结果从来都不是
True
,因此您从来没有将
param
error
字段赋值。这与你的观察结果是一致的

我怀疑您应该将
callId
设置为
string
变量,并将传递给
PConnect.callCustomfunction
的参数
callId
的值复制到该变量中。但由于我不知道你正在做什么的所有细节,我不能100%肯定

其他一些评论:

  • 你真的想给你的班级命名
    PConnect
    ?通常我们用
    T
    作为类的前缀
  • 如果使用
    for in
    循环,而不是
    while
    循环,那么代码的阅读就会容易得多
  • 包含对列表上的
    Remove
    调用的循环效率低下。您已经找到了该项,调用
    Remove
    只需再次搜索列表。实现该循环的方法是使用类
    for
    使用索引进行循环。当您找到要删除的项目时,调用
    Delete
    传递该项目的索引
  • 删除项目时,无法调用
    Dispose
    ,这意味着内存泄漏

Daniel,为什么要将旧的TP样式的对象与真实的类实例混合在一起,为什么要在字符串更有用的地方使用PAnsiChar,为什么要为每个变量重复
var
关键字?这对于德尔福来说是相当不典型的。你来自另一种语言吗?@Rudy为什么你认为这里有TP对象。在我看来,这是一张唱片。
New
的用途是堆分配一条记录并放入列表。@David:可能是因为正在
New
ed的项声明为
^CustomfunctionCallbackObject(注意最后六个字符)。对我来说,Sure看起来像一个对象,而不是一条记录。@Ken该类的名称为
PConnect
,每个局部变量前面都有
var
。所以,也许你对命名的理解太多了。此外,我经常将非TP对象的对象命名为object。对象只是一个类的实例。或者实际上是一个类型的实例。我认为记录的一个实例就是一个对象。类型具有引用或值语义这一事实并不重要。@David:是你问Rudy为什么他认为涉及TP对象的。我指出了一个怀疑的理由:
^CustomfunctionCallbackObject
new(customFunctionCallBack)
也向我暗示了这一点。“调用Dispose失败”-“免费”。您对太多语言感兴趣;)@没有。内存是由
New
分配的。所以它被处理成了
Dispose
。哦,是的-很好,我没有投反对票,那会更尴尬。@Daniel谢谢你的接受。您能告诉我们什么是
CustomfunctionCallbackObject
吗?我认为这是一个记录,因此在评论中受到了一些批评。我很想知道!