丢失TThreadList的内容

时间:2013-03-08 10:45:35

标签: multithreading delphi pascal

我遇到了问题,我的TThreadList内容似乎在我的主题中迷失了。

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

var mCustomfunctionCallbackThread: CustomfunctionCallbackThread; 

以及全局变量如下:

var mCustomfunctionCallbackThreadList: TThreadList; 

现在我在我的“PConnect”类中填充此变量,如下所示:

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条目,然后启动一个Thread:

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;  

Thread的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; 

继续问题,以下变量只是垃圾或空指针:

param:= callbackObject.param;
error:= callbackObject.error;
callId:= callbackObject.callId;

我希望它足够描述:)

我会对一些帮助感到高兴:)

1 个答案:

答案 0 :(得分:0)

当你这样做时

customfunctionCallback.callId:= id

变量id尚未初始化。这意味着你以后检查

strcomp(callbackObject.callId,callId) = 0

其行为定义不明确,因为callbackObject.callId从未初始化。然后会发生的是,您看到的定义不明确的行为是表达式永远不会评估为True,因此您永远不会分配到paramerror字段。这与您的观察结果一致。

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

其他一些评论:

  • 你真的想要为你的班级命名PConnect吗?通常我们在类前加T
  • 如果使用for in循环代替while循环,代码会更容易阅读。
  • 包含对列表中Remove的调用的循环效率低下。您已找到该项目,并且呼叫Remove只会再次搜索该列表。执行该循环的方法是使用索引的类for循环。当您找到要删除的项目时,请调用Delete传递项目的索引。
  • 删除某个项目时,您无法调用Dispose,这意味着您会泄漏内存。