تایمر براساس اصول ترد (thread) در ویندوز، بنا شده و suspend و resume می شه، ویندوز هم بنا به صلاحدید خودش ممکنه دقیقا در لحظه ای که مد نظر شماست، ترد رو ساسپند نکنه و یکم اختلاف داشته باشه، مثلا ترد با اولویت بالاتر در صف داشته باشه
تایمر بر اساس اصول ترد بنا نشده :)
تایمرها چند نوع مختلف در ویندوز دارن که نوع معمول که در اکثر زبان های برنامه نویسی منجمله Delphi استفاده میشه نوع message base ش هست ؛ این نوع تایمر ها با تابع SetTimer خودشون رو در ویندوز رجیستر میکنن و ویندوز وظیفه داره در زمان تائین شده برای Interval که در تابع SetTimer پاس داده شده به هندل پنجره ی پاس داده شده در همین تابع پبغام WM_Timer رو ارسال کنه :
procedure TTimer.UpdateTimer;
begin
KillTimer(FWindowHandle, 1);
if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
if SetTimer(FWindowHandle, 1, FInterval, nil) = 0 then
raise EOutOfResources.Create(SNoTimers);
end;
وظیفه پنجره یاد شده این هست که پیغام WM_Timer رو هندل کنه و وقتی دریافتش کرد عملیات مناسب باهاش رو انجام بده :
procedure TTimer.WndProc(var Msg: TMessage);
begin
with Msg do
if Msg = WM_TIMER then
try
Timer;
except
Application.HandleException(Self);
end
else
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;
در دلفی پیاده سازی تایمر به این صورت هست که یه پنجره مخفی در زمان ساخته شدن ترد ایجاد میشه و هندل این پنجره به تابع SetTimer ارسال میشه تا پیغام های Tick این تایمر از طرف ویندوز به این هندل ارسال بشه ( خط آخر ) :
constructor TTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True;
FInterval := 1000;
FWindowHandle := AllocateHWnd(WndProc);
end;
در ویندوز در هر ثانیه هزاران پیغام بین ویندوز و پنجره ها تبادل میشه و پیغام های زیادی هم وجود دارن که Broadcast میشن یعنی مقصد مشخصی ندارن و به همه ی پنجره های دارای هندل Valid ارسال میشن ، خوب پس Message Handler با تعداد پیغام های بسیار زیادی رو به رو هست که در صف پردازشیش ( Message Queue ) قرار دارند و باید همرو پردازش کنه و در صورت نیاز بهشون پاسخ بده ، در همین پیاده سازی تایمر دلفی در کد مربوط به override کردن تابع WndProc که در بالا قرار دادم اگر به خط آخر دقت کنید میبینید که وقتی پیغامی رسید و نوعش WM_Timer نبود دلفی تابع DefWindowProc رو صدا میزنه (API) که وظیفش صدا زدن default handler مربوطه هست تا پیغام به صورت پیش فرض پردازش بشه .
یکی از عوامل کندی تایمر دلفی به همین دلیل هست ؛ و اینکه میگید تایمرها بر اساس ترد در ویندوز پیاده سازی شدن و suspend و resume میشن درست نیست .
دیگر عامل کندی این تایمر ها این هست که به صورت User mode پیاده سازی شدن و ویندوز تضمینی بابت ارسال پیغام WM_Timer سر زمان تعیین شده نمیده و ممکنه چند میلی ثانیه اختلاف وجود داشته باشه .
اگر زمان بندی خیلی دقیقی در سناریوتون مورده نیازه باید از High Resolution Timer ها استفاده کنید ، مثل : waitable تایمرها و queue تایمرها و multimedia تایمرها
این مقاله هم نحوه استفادشون رو کامل توضیح داده : http://www.codeproject.com/Articles/...imers-Tutorial
موفق باشید .