我正在研究Delphi应用程序和Android应用程序之间的以太网数据传输服务器。 对于数据传输,我使用的是IBM的MQTT协议。
作为年轻的开发者,这个应用程序是我的第一个Real MultiThread应用程序,我的界面有点问题:
当我使用它或不时时,它会冻结很长时间(如果他出去冻结......)。 为了正确使用我的UI,我已经制作了一个非常容易使用我的界面的线程: 当一个Thread想要在我的UI上移动一个东西时,他会调用我的UIGestThread:AddItem的过程 对于不同的接口使用,我有5或6次重载此过程。
这个过程将在一个字符串列表中添加一个包含3个字符串,1个Tobject,一个单词和另一个Object类的记录类型,该列表将由线程在其执行中读取。
当线程在字符串列表中找到一个对象时,他会看到第一个,检查一个字符串,在该字符串中使用该对象。在他调用同步调用的方法后,修改我的UI。
但它冻结,如果有人可以帮助我,谢谢你;) 对不起我的英语,我正在学习;)
编辑1: 在对我的线程进行一点修改后,我发布了新代码,如果它可以提供帮助的话。 这个线程有一个更好的立场,而不是冻结加上界面,并允许在界面上保持响应应用程序的更多操作。
是的,我在这里发生了内存泄漏,我不明白为什么:
我的线程的例子:(我认为它不可用)
// My type of pointer used in the following code:
TIhmActRec = record
public
sMsg: TMsgString;
sMsg2: TMsgString;
sMsg3: TMsgString;
sTop: TTopString;
iInteg1,iInteg2,iInteg3:integer;
bBool:boolean;
def:TDefHandle;
end;
PTIhmActRec = ^TIhmActRec;
我的应用程序的另一个线程可以调用AddItem来向接口添加订单。 AddItem有8个可能,比如配置订单的3个例子。
procedure TGestionIHMThread.AddItem(s1: String);
var
str: PTIhmActRec;
begin
new(str); //Create of an new pointer
str^.sTop := LeftStr(s1, 5); //Init of value
ListThreadItem.Add(str); //Add to a ThreadList
end;
procedure TGestionIHMThread.AddItem(s1: String; i1, i2, i3: integer);
var
str: PTIhmActRec;
begin
new(str);
str^.sTop := LeftStr(s1, 5);
str^.iInteg1 := i1;
str^.iInteg2 := i2;
str^.iInteg3 := i3;
ListThreadItem.Add(str);
end;
procedure TGestionIHMThread.AddItem(s1: String; def: TDefHandle);
var
str: PTIhmActRec;
begin
new(str);
str^.sTop := LeftStr(s1, 5);
str^.def := def;
ListThreadItem.Add(str);
end;
Thread在线程列表中添加了一个对象后,Execute过程将获取该对象 并调用程序CallMajIhm(Object)以使用它
procedure TGestionIHMThread.Execute;
var
str: PTIhmActRec; //Pointeur for take new item
begin
repeat
try
with ListThreadItem.LockList do
try
if (Count > 0) then
begin
str := First; //Take item in pointer
Delete(0); //Delete first case of my list
end
else
str := nil;
finally
ListThreadItem.UnlockList;
end;
if ((str <> nil)) then
begin
try
CallMajIhm(str); //Launch CallMajIhm
finally
str := nil;
end;
end;
sleep(10);
Except
//
end;
until Terminated;
end;
// CallMajIhm将其他List中的值存入并启动对象询问的过程// Queue下的消息,以便与UI同步。
procedure TGestionIHMThread.CallMajIhm(Messages: PTIhmActRec);
begin
try
sTxtCall1 := Messages.sTop;
ListForQueueIssue.Add(Messages);
if sTxtCall1 = 'FLBNC' then
begin
Queue(CallFMQTTListBoxNrClear);
end
else if sTxtCall1 = 'FLBNA' then
begin
Queue(CallFMQTTListBoxNrAdd);
end
else if sTxtCall1 = 'FLBND' then
begin
Queue(CallFMQTTListBoxNrDel);
end
finally
// RAZ des valeurs afin d'etre sur qu'elle ne soit pas réutilisé suite a un bug...
sTxtCall1 := '';
end;
end;
//在Queue下调用的每个过程都采用相同的格式:
procedure TGestionIHMThread.CallFMQTTListBoxNrClear;
begin
try
trytakeitem; //Take the Order
if PValForQueue.sTop = 'FLBNC' then //Verify if it's the good order
if FormTestMQTT.ListBoxnr <> nil then //Verify if the UI's object existing before
FormTestMQTT.ListBoxnr.Clear; //Make the Order
finally
Dispose(PValForQueue); //Dispose the Order
PValForQueue:= nil; //Forget the Order
end;
end;
procedure TGestionIHMThread.CallFMQTTListBoxNrAdd;
begin
try
trytakeitem;
if PValForQueue.sTop = 'FLBNA' then
if FormTestMQTT.ListBoxnr <> nil then
FormTestMQTT.ListBoxnr.Items.Add(PValForQueue.sMsg);
finally
Dispose(PValForQueue);
PValForQueue:= nil;
end;
end;
procedure TGestionIHMThread.CallFMQTTListBoxNrDel;
begin
try
trytakeitem;
if PValForQueue.sTop = 'FLBND' then
if FormTestMQTT.ListBoxnr <> nil then
if FormTestMQTT.ListBoxnr.Items.IndexOf(PValForQueue.sMsg) <> -1 then
FormTestMQTT.ListBoxnr.Items.Delete
(FormTestMQTT.ListBoxnr.Items.IndexOf(PValForQueue.sMsg));
finally
Dispose(PValForQueue);
PValForQueue:= nil;
end;
end;
//Procedure which take the order in the threadlist :
procedure TGestionIHMThread.trytakeitem;
var
iCpt : integer;
begin
iCpt:=0;
with ListForQueueIssue.LockList do
try
if (Count > 0) then
begin
iCpt:=Count;
PValForQueue := First;
Delete(0);
end
else
PValForQueue := nil;
finally
ListForQueueIssue.UnlockList;
end;
end;
// 编辑1: // 我认为原来的问题已经解决但我在这个函数中有内存泄漏:我对Queue的使用是否正确?因为如果线程调用proc&#34; AddItem&#34;太多了,ListForQueueIssue增长,没有安全性,内存泄漏继续增长......