我刚刚意识到我的异常没有在我的线程中向用户显示!
起初我在我的线程中使用它来引发异常,这不起作用:
except on E:Exception do
begin
raise Exception.Create('Error: ' + E.Message);
end;
Run Code Online (Sandbox Code Playgroud)
IDE向我显示了异常,但我的应用程序没有!
我四处寻找解决方案,这就是我发现的:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22039681.html
这些都不适合我.
这是我的Thread单元:
unit uCheckForUpdateThread;
interface
uses
Windows, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP, GlobalFuncs, Classes, HtmlExtractor, SysUtils, Forms;
type
TUpdaterThread = class(TThread)
private
FileGrabber : THtmlExtractor;
HTTP : TIdHttp;
AppMajor,
AppMinor,
AppRelease : Integer;
UpdateText : string;
VersionStr : string;
ExceptionText : string;
FException: Exception;
procedure DoHandleException;
procedure SyncUpdateLbl;
procedure SyncFinalize;
public
constructor Create;
protected
procedure HandleException; virtual;
procedure Execute; override;
end;
implementation
uses …Run Code Online (Sandbox Code Playgroud) 在给定的示例中,我在调用时收到异常 AThread.Free.
program Project44;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Windows;
type
TMyException = class(Exception);
var
AThread: TThread;
begin
AThread := TThread.Create(True);
try
AThread.FreeOnTerminate := True;
//I want to do some things here before starting the thread
//During the setup phase some exception might occur, this exception is for simulating purpouses
raise TMyException.Create('exception');
except
AThread.Free; //Another exception here
end;
end.
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
我应该如何释放AThread的实例TThread在给定的例子吗?
我不明白,为什么TThread.Destroy呼吁Resumedestroing本身之前.这有什么意义?
据我了解并了解TThread类的方法,如果你同步你的代码,它实际上是在主应用程序线程中执行的(就像一个计时器/按钮点击/等).我一直在玩,并注意到MessageBox不会阻止主应用程序,但是睡眠就像预期的那样.这是为什么?
type
TTestThread = class(TThread)
private
procedure SynchThread;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
end;
procedure TTestThread.SynchThread;
begin
MessageBoxA (0, 'Hello', 'Test', 0);
end;
procedure TTestThread.Execute;
begin
Synchronize (SynchThread)
end;
constructor TTestThread.Create(CreateSuspended: Boolean);
begin
inherited;
FreeOnTerminate := True;
end;
procedure StartThread;
var
TestThread : TTestThread;
begin
TestThread := TTestThread.Create (FALSE);
end;
Run Code Online (Sandbox Code Playgroud) 在TThread实例创建和启动之间,主线程将继续执行代码.如果主线程中的代码依赖于有问题的线程完全启动并运行它必须以某种方式等待直到线程Execute方法实际启动.
考虑以下代码:
const
WM_MY_ACTION = WM_APP + 10;
type
TWndThread = class(TThread)
protected
fWndHandle: THandle;
IsRunning: boolean;
procedure WndProc(var Msg: TMessage);
procedure Execute; override;
public
Test: integer;
procedure AfterConstruction; override;
procedure DoAction;
end;
procedure TWndThread.AfterConstruction;
begin
inherited;
while not IsRunning do Sleep(100); // wait for thread start up
end;
procedure TWndThread.Execute;
var
Msg: TMsg;
begin
fWndHandle := AllocateHWnd(WndProc);
IsRunning := true;
try
while not Terminated do
begin
if MsgWaitForMultipleObjects(0, nil^, False, 1000, QS_ALLINPUT) = WAIT_OBJECT_0 then …Run Code Online (Sandbox Code Playgroud) 我有一个用C++编写的Windows DLL的源代码,并使用Visual Component Library.现在我的任务是将其移植到Linux,但我没有VCL本身的源代码或任何类型的文档(我从未使用过Borland C++;在我的Windows时代,我使用过MFC).
这应该不是那么难,因为我的DLL没有任何GUI:据我所知,它主要使用VCL进行多线程处理.我遇到了一个继承自TThread的类,这就是我遇到的问题.我在互联网上做了一些搜索,但到目前为止还没有找到VCL的文档.我想避免购买一本关于Borland C++ Builder的书,因为我没有时间等待它从亚马逊到达.我不能考虑购买Windows的软件包,因为在工作中我只有一个Linux盒子.
有什么建议?
我有一个简单的Delphi程序,我正在努力,我试图使用线程将程序的功能与其GUI分离,并在更冗长的任务期间保持GUI响应等.基本上,我有一个'控制器'TThread和'视图'TForm.视图知道控制器的句柄,它用于通过控制器发送控制器消息PostThreadMessage.我过去没有问题使用这种模型用于不是主要形式的表单,但出于某种原因,当我尝试将此模型用于主表单时,线程的消息循环才会退出.
这是我的线程消息循环的代码:
procedure TController.Execute;
var
Msg : TMsg;
begin
while not Terminated do begin
if (Integer(GetMessage(Msg, hwnd(0), 0, 0)) = -1) then begin
Synchronize(Terminate);
end;
TranslateMessage(Msg);
DispatchMessage(Msg);
case Msg.message of
// ...call different methods based on message
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
要设置控制器,我这样做:
Controller := TController.Create(true); // Create suspended
Controller.FreeOnTerminate := True;
Controller.Resume;
Run Code Online (Sandbox Code Playgroud)
为了处理主表单的消息,我尝试使用两个Application.Run和以下循环(紧接在后面Controller.Resume)
while not Application.Terminated do begin
Application.ProcessMessages;
end;
Run Code Online (Sandbox Code Playgroud)
我已经被困在这里 - 任何帮助将不胜感激.
我有一个耗时的例程,我想使用Delphi XE7的新并行库并行处理.
这是单线程版本:
procedure TTerritoryList.SetUpdating(const Value: boolean);
var
i, n: Integer;
begin
if (fUpdating <> Value) or not Value then
begin
fUpdating := Value;
for i := 0 to Count - 1 do
begin
Territory[i].Updating := Value; // <<<<<< Time consuming routine
if assigned(fOnCreateShapesProgress) then
fOnCreateShapesProgress(Self, 'Reconfiguring ' + Territory[i].Name, i / (Count - 1));
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
实际上并没有什么复杂的事情发生.如果区域列表变量已更改或设置为false,则例程将循环遍历所有销售区域并重新创建区域边界(这是一项耗时的任务).
所以这是我试图让它平行:
procedure TTerritoryList.SetUpdating(const Value: boolean);
var
i, n: Integer;
begin
if (fUpdating <> Value) or not Value then
begin
fUpdating := …Run Code Online (Sandbox Code Playgroud) 我有一个TThread对象,希望能够通过程序主窗体上的按钮启动/停止线程.我一直在研究如何做到这一点,到目前为止,我有以下想法:
我倾向于#3.在主窗体上设置TThread对象的布尔属性是线程安全吗?
我应该选择哪些选项或更好的选择?这是我第一次使用线程,所以任何帮助都表示赞赏.
使用的版本: Delphi 7.
我正在开发一个在Virtual ListView上执行简单for循环的程序.数据存储在以下记录中:
type TList=record
Item:Integer;
SubItem1:String;
SubItem2:String;
end;
Run Code Online (Sandbox Code Playgroud)
项目是索引.SubItem1操作的状态(成功与否).SubItem2文件的路径.在对循环加载每个文件,做一些操作,然后保存.操作发生在TStringList中.文件大约每个2mb.
现在,如果我在主窗体上执行操作,它可以完美地工作.
多线程,存在巨大的内存问题.不知何故,TStringList似乎没有被完全释放.在3-4k文件之后,我得到一个EOutofMemory异常.有时候,软件会停留在500-600mb,有时候不会.在任何情况下,TStringList始终返回EOutofMemory异常,并且不再可以加载任何文件.在具有更多内存的计算机上,获取异常需要更长时间.
其他组件也会发生同样的事情.例如,如果我使用Synapse的THTTPSend,过了一段时间,软件无法创建任何新线程,因为内存消耗太高.它大概是500-600mb,而它应该是,最大,100mb.在主窗体上,一切正常.
我想这个错误就在我身边.也许我不太了解线程.我试图释放Destroy事件中的所有内容.我尝试过FreeAndNil程序.我一次只尝试一个线程.我尝试手动释放线程(没有FreeOnTerminate ......)
没运气.
所以这是线程代码.这只是基本的想法; 不是所有操作的完整代码.如果我删除LoadFile prodecure,一切都很好.根据线程池为每个文件创建一个线程.
unit OperationsFiles;
interface
uses Classes, SysUtils, Windows;
type
TOperationFile = class(TThread)
private
Position : Integer;
TPath, StatusMessage: String;
FileStringList: TStringList;
procedure UpdateStatus;
procedure LoadFile;
protected
procedure Execute; override;
public
constructor Create(Path: String; LNumber: Integer);
end;
implementation
uses Form1;
procedure TOperationFile.LoadFile;
begin
try …Run Code Online (Sandbox Code Playgroud) 我一直在尝试实现一个在后台运行的线程,并且每隔一秒左右更新一个进度条,并按照Delphi的最佳答案中的示例- 在线程内部的计时器生成AV.我注意到建议的解决方案有TThread.FinishThreadExecution的实现.我的IDE显示我的delphi版本支持该方法,但我一直无法找到它的任何文档(谷歌出现10次点击,没有一个帮助,http://docwiki.embarcadero.com/没有列出TThread下的那个方法.它的用途是什么,什么时候被称为?
tthread ×10
delphi ×9
exception ×2
vcl ×2
c++builder ×1
delphi-2009 ×1
memory ×1
messages ×1
pause ×1
raise ×1
ram ×1
tstringlist ×1