Delphi XE8 TThread 在 Android 上冻结,但在 Windows 上运行
Delphi XE8 TThread Frozen on Android, but works on Windows
我将一个线程和一个同步过程用于一个简单的游戏循环。
在我的电脑上,Windows 7,它非常有效,但是当我在我的 android 设备上 运行 它并且在我点击播放和线程启动后屏幕变黑或有时变暗,有时它保持正常,但屏幕上所有可见的对象要么拉伸要么无法正确渲染;此时线程似乎被冻结了(主窗体的音乐仍在继续播放)。
这是线程本身:
procedure TTheThread.Loop;
begin
MainForm.GameLoop;
end;
procedure TTheThread.Execute;
begin
while NOT Terminated do
begin
Application.ProcessMessages;
TC:= TStopwatch.GetTimeStamp;
//The Following repeats itself every second:
if TC>(TCTime+10000000) then
begin
TCTime:= TStopwatch.GetTimeStamp;
TimeT:= TimeT+1; //Time in seconds
//Increasing game playing speed:
Gravity:= Gravity + 0.0075 * DEF;
PJump:= PJump+IncJump
end;
//...just to have it on screen:
With MainForm do
Label1.Text:= IntToStr(TC);
//This seems to make the loop run smooth and without lagging on my PC:
if TC>(TCLast) then
begin
Synchronize(Loop);
TCLast:= TC;
end;
end;
end;
它是这样开始的:
TCTime:= TStopwatch.GetTimeStamp;
TCLast:= TCTime;
GameThread:= TTheThread.Create(True);
GameThread.FreeOnTerminate:= True;
GameThread.Start;
您的线程中有一些不安全的代码,很容易导致死锁和死亡 UIs(以及其他问题)。 不要直接在线程中访问UI控件,您必须与主UI线程同步,例如与TThread.Synchronize()
或 TThread.Queue()
,例如:
TThread.Synchronize(nil,
procedure
begin
MainForm.Label1.Text := IntToStr(TC);
end
);
此外,也不要在线程中调用 Application.ProcessMessages()
。它仅属于主 UI 线程。即便如此,如果您必须报告调用它,那么您很可能一开始就做错了。在正常情况下,您永远不必诉诸手动调用它。
我将一个线程和一个同步过程用于一个简单的游戏循环。 在我的电脑上,Windows 7,它非常有效,但是当我在我的 android 设备上 运行 它并且在我点击播放和线程启动后屏幕变黑或有时变暗,有时它保持正常,但屏幕上所有可见的对象要么拉伸要么无法正确渲染;此时线程似乎被冻结了(主窗体的音乐仍在继续播放)。
这是线程本身:
procedure TTheThread.Loop;
begin
MainForm.GameLoop;
end;
procedure TTheThread.Execute;
begin
while NOT Terminated do
begin
Application.ProcessMessages;
TC:= TStopwatch.GetTimeStamp;
//The Following repeats itself every second:
if TC>(TCTime+10000000) then
begin
TCTime:= TStopwatch.GetTimeStamp;
TimeT:= TimeT+1; //Time in seconds
//Increasing game playing speed:
Gravity:= Gravity + 0.0075 * DEF;
PJump:= PJump+IncJump
end;
//...just to have it on screen:
With MainForm do
Label1.Text:= IntToStr(TC);
//This seems to make the loop run smooth and without lagging on my PC:
if TC>(TCLast) then
begin
Synchronize(Loop);
TCLast:= TC;
end;
end;
end;
它是这样开始的:
TCTime:= TStopwatch.GetTimeStamp;
TCLast:= TCTime;
GameThread:= TTheThread.Create(True);
GameThread.FreeOnTerminate:= True;
GameThread.Start;
您的线程中有一些不安全的代码,很容易导致死锁和死亡 UIs(以及其他问题)。 不要直接在线程中访问UI控件,您必须与主UI线程同步,例如与TThread.Synchronize()
或 TThread.Queue()
,例如:
TThread.Synchronize(nil,
procedure
begin
MainForm.Label1.Text := IntToStr(TC);
end
);
此外,也不要在线程中调用 Application.ProcessMessages()
。它仅属于主 UI 线程。即便如此,如果您必须报告调用它,那么您很可能一开始就做错了。在正常情况下,您永远不必诉诸手动调用它。