gpt4 book ai didi

mysql - 在启动时调度服务

转载 作者:行者123 更新时间:2023-11-29 02:03:22 25 4
gpt4 key购买 nike

我使用 BDS 2006 开发了一个应用程序,它使用 MySQL 数据库(使用 DataModule 和 MyDAC 组件连接)。
现在我想在系统启动时启动我的应用程序(Windows XP)。所以我包括了 application shortcut in the start up folder .

现在启动,我的应用程序在 MySQL 服务启动之前启动。因此我得到一个错误无法连接到 MySQL

所以我在我的应用程序启动时插入了一个空白,并执行检查以查看 MySQL 是否正在运行。如果未运行,则等待它运行。

function ServiceGetStatus(sMachine, sService: PChar): DWORD;
{******************************************}
{*** Parameters: ***}
{*** sService: specifies the name of the service to open
{*** sMachine: specifies the name of the target computer
{*** ***}
{*** Return Values: ***}
{*** -1 = Error opening service ***}
{*** 1 = SERVICE_STOPPED ***}
{*** 2 = SERVICE_START_PENDING ***}
{*** 3 = SERVICE_STOP_PENDING ***}
{*** 4 = SERVICE_RUNNING ***}
{*** 5 = SERVICE_CONTINUE_PENDING ***}
{*** 6 = SERVICE_PAUSE_PENDING ***}
{*** 7 = SERVICE_PAUSED ***}
{******************************************}
var
SCManHandle, SvcHandle: SC_Handle;
SS: TServiceStatus;
dwStat: DWORD;
begin
dwStat := 0;
// Open service manager handle.
SCManHandle := OpenSCManager(sMachine, nil, SC_MANAGER_CONNECT);
if (SCManHandle > 0) then
begin
SvcHandle := OpenService(SCManHandle, sService, SERVICE_QUERY_STATUS);
// if Service installed
if (SvcHandle > 0) then
begin
// SS structure holds the service status (TServiceStatus);
if (QueryServiceStatus(SvcHandle, SS)) then
dwStat := ss.dwCurrentState;
CloseServiceHandle(SvcHandle);
end;
CloseServiceHandle(SCManHandle);
end;
Result := dwStat;
end;

code source

// if MySQL not running then sleep until its running
procedure TForm1.FormCreate(Sender: TObject);
begin
while(ServiceGetStatus(nil, 'MySQL5.5') <>4 ) do
begin
sleep (200);
end;
end;

我想知道我的做法是否正确?如果不建议相同。
也可以不用windows编程也能做到吗?

最佳答案

在主线程中休眠从来都不是一个好主意。

最好在线程中进行等待,并在 MySQL 运行时向主线程发送消息。

回复@mghie 的评论:

Why would waiting on the event be any better (or any different) than calling Sleep()?

事件驱动的 GUI 被认为是良好的编程习惯。无需等待。当事件被激发时,GUI 被告知数据库连接的状态变化。如果您将在 Sleep() 循环中等待,应用程序将显示为无响应。并调用 Application.ProcessMessages 来某种程度上解决这个问题,这确实不是一个好的做法。

如何等待 MySQL 在线程中运行的示例:

const
WM_MySQL_READY = WM_USER + 1; // The unique message id

type
TForm1 = class(TForm)
...
private
procedure OnMySqlReady( var Msg: TMessage); message WM_MySQL_READY;
...
end;

在您的主题中:

Constructor TMyThread.Create( OwnerForm : TForm);
begin
Inherited Create( false);
FOwnerForm := OwnerForm; // Keep for later use
Self.FreeOnTerminate := true;
end;

procedure TMyThread.Execute;
var
SQL_started : boolean;
sleepEvent : TSimpleEvent;
begin
sleepEvent := TSimpleEvent.Create;
try
repeat
SQL_started := (ServiceGetStatus(nil, 'MySQL5.5') = 4);
sleepEvent.WaitFor(200); // Better than sleep();
until SQL_started or Terminated;
finally
sleepEvent.Free;
end;
// Inform main thread
PostMessage( FOwnerForm.Handle,WM_MySQL_READY,WPARAM(SQL_started),0);
end;

好吧,我有点误解@mghie,他的问题是为什么线程内的TSimpleEvent.WaitFor() 比Sleep() 好

有关背景,请参阅:thread-sleep-is-a-sign-of-a-poorly-designed-program .

简而言之,Sleep() 将线程置于深度 sleep 状态并且控制权不会以最佳周期率返回(如果在某些极端情况下出现)。

另一方面,

TSimpleEvent.WaitFor() 在计时和唤醒方面响应更快。 (请记住,Windows 不是真正的实时操作系统,无法保证时间)。不管怎样,根据经验,在线程中使用 TSimpleEvent.Waitfor() 而不是 Sleep()。

如果需要停止等待连接到 MySQL 服务器,可以对代码进行一些调整:

constructor TMyThread.Create(OwnerForm: TForm; cancelEvent : TSimpleEvent);
begin
inherited Create(false);
FOwnerForm := OwnerForm; // Make sure it's assigned
FCancelEvent := cancelEvent; // Make sure it's assigned
Self.FreeOnTerminate := true;
end;

procedure TMyThread.Execute;
var
SQL_started : boolean;
cancel : boolean;
begin
repeat
SQL_started := (ServiceGetStatus(nil, 'MySQL5.5') = 4);
cancel := (FCancelEvent.WaitFor(200) = wrSignaled);
until SQL_started or Terminated or cancel;
// Inform main thread
PostMessage( FOwnerForm.Handle,WM_MySQL_READY,WPARAM(SQL_started),0);
end;

要在建立连接之前中止线程,只需调用 MyEvent.SetEvent。


如果您想通知用户等待期间发生的事情,您甚至可以从线程中显示启动画面。

参见 Peter Below's Threaded Splashscreen for Delphi对于这样的例子。请注意,此代码不使用任何 VCL 组件或任何涉及与主线程同步的内容。

您可能还想看看:Show a splash screen while a database connection (that might take a long time) runs .

关于mysql - 在启动时调度服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10860234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com