来吧,朋友,分---好多,很容易赚(200分)

  • 主题发起人 主题发起人 helpme2002
  • 开始时间 开始时间
H

helpme2002

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟在NT下写了一个SERVICE,其中用到了一个线程,该线程每一分钟运行一次,处理数据库
,运行“正常”,但我的NT却关不了机,老是要结束我的SERVICE进程(等待,立即结束,取消)
(我的这个SERVICE安装正常,在NT的服务面板中也启动,停止正常),WHY??????

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
// showmessage('ddd');
database.Create(false);
Started := True;

end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
//CoInitialize(nil) ;
database.Create(false).Terminate;
Stopped := True;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
database.Create(false).Suspend;
Paused := True;
end;

procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
database.Create(false).Resume;
Continued := True;
end;

procedure TService1.ServiceShutdown(Sender: TService);
begin
database.Create(false).Terminate;

end;

procedure TService1.ServiceDestroy(Sender: TObject);
begin
database.Create(false).Destroy;

end;
 
database.Create(false).Terminate; 這樣的用法挺怪的
 
呵呵,我的线程叫database
 
把这个控件替换调time控件,再ontime事件里写下你的要作的事。在form的close事件
写下
begin
ThreadTimer1.Destroy;
close;
Application.Terminate;
end;
现在就不会出现你的情况了,可能是你的thread没有处理好
下面是thread timer控件。
unit ThdTimer;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;

const
DEFAULT_INTERVAL = 1000;

type
TThreadedTimer = class;

TTimerThread = class(TThread)
private
FOwner: TThreadedTimer;
FInterval: longWord;
FStop: THandle;
protected
constructor Create(CreateSuspended: Boolean); virtual;
procedure Execute; override;
end;

TThreadedTimer = class(TComponent)
private
FEnabled: Boolean;
FOnTimer: TNotifyEvent;
FTimerThread: TTimerThread;

procedure DoTimer;

procedure SetEnabled(Value: Boolean);
function GetInterval: LongWord;
procedure SetInterval(Value: LongWord);
function GetThreadPriority: TThreadPriority;
procedure SetThreadPriority(Value: TThreadPriority);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

published
property Enabled: Boolean read FEnabled write SetEnabled;
property Interval: LongWord read GetInterval write SetInterval
default DEFAULT_INTERVAL;
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
property ThreadPriority: TThreadPriority read GetThreadPriority
write SetThreadPriority;
end;

procedure Register;

implementation

{ TTimerThread }

constructor TTimerThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);

// create event object for signaling interruptions
FStop := CreateEvent(nil, False, False, nil);
end;

procedure TTimerThread.Execute;
begin
repeat
// wait for time elapse
if WaitForSingleObject(FStop, FInterval) = WAIT_TIMEOUT then
// if time elapsed run user-event
Synchronize(FOwner.DoTimer);
until Terminated;

// Delete event object
CloseHandle(FStop);
end;

{ TThreadedTimer }

constructor TThreadedTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);

// create timer thread
FTimerThread := TTimerThread.Create(True);
FTimerThread.FOwner := Self;
FTimerThread.FreeOnTerminate := False;
FTimerThread.Priority := tpNormal;
FTimerThread.FInterval := DEFAULT_INTERVAL;
end;

destructor TThreadedTimer.Destroy;
begin
// Destroy thread
// signal thread to terminate
FTimerThread.Terminate;
SetEvent(FTimerThread.FStop);
// resume if stopped
if FTimerThread.Suspended then FTimerThread.Resume;
// wait and free
FTimerThread.WaitFor;
FTimerThread.Free;

inherited Destroy;
end;

procedure TThreadedTimer.DoTimer;
begin
if Assigned(FOnTimer) then
FOnTimer(self);
end;

procedure TThreadedTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;

if FEnabled then
begin
// When enabled resume thread
if FTimerThread.FInterval > 0 then
begin
SetEvent(FTimerThread.FStop);
FTimerThread.Resume;
end;
end
else
// suspend thread
FTimerThread.Suspend;
end;
end;

function TThreadedTimer.GetInterval: LongWord;
begin
Result := FTimerThread.FInterval;
end;

procedure TThreadedTimer.SetInterval(Value: LongWord);
begin
if Value <> FTimerThread.FInterval then
begin
Enabled := False;
FTimerThread.FInterval := Value;
end;
end;

function TThreadedTimer.GetThreadPriority: TThreadPriority;
begin
Result := FTimerThread.Priority;
end;

procedure TThreadedTimer.SetThreadPriority(Value: TThreadPriority);
begin
FTimerThread.Priority := Value;
end;

procedure Register;
begin
RegisterComponents('System', [TThreadedTimer]);
end;

end.
 
有没有用FastNet里面的那套TNMXXX的控件?
 
教父:没有
l_x_yuan:我没用TIME控件,我的程序休眠用了sleep(600000)
 
我不太清楚,给分吧!
 
engineer:呵呵,先回答再给你晒
 
在sleep过程时程序不会响应任何消息,所以你没有办法关闭它,你把sleep改成如下代码试

procedure wait(waittime : DWORD);
var
StartTime : DWORD;
begin
StartTime := GetTickCount;
while GetTickCount-StartTime<waittime do
begin
Application.ProcessMessage;
end;
end;

还有,你每运行database.Create(false).一次就会创建一个线程,你这里不止一个线程了,
而且你也没办法控制它们啊?
 
我觉得应该截获windows的关机消息,然后让程序自动结束。
 
教父兄弟:请教一个问题,我的线程只有一个DATABASE,为什么会每次都创建呢?,在
TService1.ServiceStart时只创建一次,然后TService1就去执行线程了啊,再在线程里

WHILE TRUE DO
BEGIN
代码
SLEEP(600000)
END
我这样做对吗?

 
再请教DWORD类型,需要USE什么文件?
 
procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
// showmessage('ddd');
database.Create(false); //这里会创建一个!假设它是线程A
Started := True;

end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
//CoInitialize(nil) ;
database.Create(false).Terminate; //这里也会创建一个!这个和A肯定不是一样,
//而且它一创建后立刻终止,而A还在。
Stopped := True;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
database.Create(false).Suspend;//这里又会创建一个!
Paused := True;
end;

procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
database.Create(false).Resume;//这里又会创建一个!
Continued := True;
end;

procedure TService1.ServiceShutdown(Sender: TService);
begin
database.Create(false).Terminate;//这里又会创建一个!
end;

procedure TService1.ServiceDestroy(Sender: TObject);
begin
database.Create(false).Destroy;//这里又会创建一个!
end;

所以我说你每运行database.Create(false).一次就会创建一个线程,而且都不是你在
TService1.ServiceStart时创建的那一个线程A。
线程里应该用
WHILE not terminated DO
BEGIN
//代码
SLEEP(600000)
END
否则你的Thread.Terminate并不能终止一个线程,我想这就是你的程序为什么会关不掉的主
要原因。

DWORD在windows单元中定义的。

 
刚才试了一下,在线程中用sleep仍然可以关闭程序,呵呵,不好意思。
 
教父兄弟:如果我要将database.Create(false)赋值给一个值DATATHREAD,这个值该用什么
类型?USE?
我这样,你看如何:

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
// showmessage('ddd');
DATATHREAD:= database.Create(false);
Started := True;

end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
//CoInitialize(nil) ;
DATATHREAD.Terminate;
Stopped := True;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
DATATHREAD.Suspend;
Paused := True;
end;

procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
DATATHREAD.Resume;
Continued := True;
end;

procedure TService1.ServiceShutdown(Sender: TService);
begin
DATATHREAD.Terminate;

end;

procedure TService1.ServiceDestroy(Sender: TObject);
begin
DATATHREAD.Destroy;

end;

还会创建很多的THREAD吗?否则应该如何?
 
ServiceStop
ServicePause
ServiceContinue等过程用缺省的吗
 
这样应该就没问题了。“用缺省的”是什么意思?
在其实过程中最好加上一句判断,如:
if Assigned(DATATHREAD) then DATATHREAD.Terminate;
 
教父兄弟:
DATATHREAD,这个值该用什么
类型?USE?我的D6告诉我Undeclared identifier:'DATATHREAD'
 
后退
顶部