View Full Version : استفاده از فیلد های یک کامپوننت در Thread
AliReza Vafakhah
شنبه 22 خرداد 1389, 03:39 صبح
سلام دوستان
یک کامپوننت جستجو نوشتم که فایل های موجود در یک دایرکتوری را جستجو می کنه و مشکلی هم نداره (از نظر جستجو) اما تو کلاس کامپوننت که از TComponent مشتق شده چندتا فیلد تعریف کردم که دوتاشون مربوط می شوند به تعداد فایل های اسکن شده و دیگری تعداد دایرکتوری های اسکن شده و هر دو از نوع عددی (Integer). سپس تابع جستجو را هم با یک Thread پیدا سازی کردم و خلاصه چون یک فیلد از نوع TStrings در کلاس کامپوننت تعریف کردم به همین دلیل مجبور شدم در کلاس Thread هم یه فیلد تعریف کنم و در هنگام Create ترد اون را مقدار دهی کنم ، اما مشکل من اینجا است که نمیتوانم در تابع جستجو به فیلدهای کلاس کامپوننت دسترسی پیدا کنم
البته اگر به فیلدهای کامپوننت دسترسی پیدا کنم دیگر نیاز به تعریف مجدد فیلدی از نوع TStrings در کلاس Thread نخواهم داشت.
AliReza Vafakhah
سه شنبه 25 خرداد 1389, 03:12 صبح
دوستان حتی با ارسال پیغام بین Thread و کلاس کامپوننت موفق نشدم که هنگام Terminate شدن Thread با دستور SendMessage پیغامی که از WM_USER+1369 استفاده کرده بود ، را برای کلاس کامپوننت مبنی بر این که کار Thread تمام شده ارسال کنم.
دوستان راهنمایی کنید.
SAASTN
سه شنبه 25 خرداد 1389, 09:11 صبح
اما مشکل من اینجا است که نمیتوانم در تابع جستجو به فیلدهای کلاس کامپوننت دسترسی پیدا کنم
خیلی گویا نیست. با خطا روبرو می شین یا سینتکس اجازه دسترسی نمی ده. اگه می شه یه شمه از کدتو بذار.
دوستان حتی با ارسال پیغام بین Thread و کلاس کامپوننت موفق نشدم که هنگام Terminate شدن Thread با دستور SendMessage پیغامی که از WM_USER+1369 استفاده کرده بود ، را برای کلاس کامپوننت مبنی بر این که کار Thread تمام شده ارسال کنم.
اینم گویا نیست. کجا منتظر دریافت Message بودین؟ MessageHandler مربوط به اون کد رو نوشتین؟
vcldeveloper
سه شنبه 25 خرداد 1389, 11:15 صبح
یک کامپوننت نوشتید که در داخل خودش یک Thread را برای جستجو اجرا میکنه. Thread شما پارامترهای مورد نیازش را از کامپوننت میگیره، و نتیجه را هم از طریق کامپوننت برمیگردونه.
دسترسی به فیلدهایی مثل تعداد فایل ها یا پوشه های اسکن شده باید Synchronize شده باشه، یعنی هم Thread مربوطه، و هم کامپوننت برای دسترسی به این داده ها باید از تکنیک های Synchronization استفاده کنند. برای این دو موردی که ذکر کردید، کلاس TMultiReadExclusiveWriteSynchronizer مناسب هست.
نتیجه اجرای thread هم متناسب با هدف شما، باید به شکل مناسبی برگشت داده بشه؛ اگر قرار هست نتیجه در پایان کار Thread برگشت داده بشه، می تونید از رویداد OnTerminate اون Thread برای دریافت نتیجه استفاده کنید. اگر قرار هست که Thread به ازاء پیدا کردن هر فایل، نتیجه را بلافاصله برگشت بده، اون وقت می تونید از تکنیک های مختلفی استفاده کنید، یکیش این هست که Thread به یک پنجره مشخص پیام ارسال کنه، یکی دیگش این هست که Thread با استفاده از متد Queue مربوط به TThread، کدی را در یک Thread دیگه (به طور خاص، Thread اصلی) فراخوانی کنه.
AliReza Vafakhah
پنج شنبه 27 خرداد 1389, 00:13 صبح
یک کامپوننت نوشتید که در داخل خودش یک Thread را برای جستجو اجرا میکنه. Thread شما پارامترهای مورد نیازش را از کامپوننت میگیره، و نتیجه را هم از طریق کامپوننت برمیگردونه.
دسترسی به فیلدهایی مثل تعداد فایل ها یا پوشه های اسکن شده باید Synchronize شده باشه، یعنی هم Thread مربوطه، و هم کامپوننت برای دسترسی به این داده ها باید از تکنیک های Synchronization استفاده کنند. برای این دو موردی که ذکر کردید، کلاس TMultiReadExclusiveWriteSynchronizer مناسب هست.
آقای کشاورز میشه یک مثال هم بزنید ؛ تشکر
vcldeveloper
پنج شنبه 27 خرداد 1389, 00:59 صبح
آقای کشاورز میشه یک مثال هم بزنید ؛
interface
uses
SysUtils, Classes;
type
TTestThread = class(TThread)
private
FDirCount : Integer;
FSync : TMREWSync;
function GetDirCount: Integer;
procedure SetDirCount(Value: Integer);
protected
procedure Execute; override;
property DirCount: Integer read GetDirCount write SetDirCount;
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
end;
implementation
{ TTestThread }
constructor TTestThread.Create(CreateSuspended: Boolean);
begin
inherited Create(True);
FSync := TMREWSync.Create;
if CreateSuspended then
Resume;
end;
destructor TTestThread.Destroy;
begin
FSync.Free;
inherited;
end;
procedure TTestThread.Execute;
begin
{ Place thread code here }
end;
function TTestThread.GetDirCount: Integer;
begin
FSync.BeginRead;
try
Result := FDirCount;
finally
FSync.EndRead;
end;
end;
procedure TTestThread.SetDirCount(Value: Integer);
begin
FSync.BeginWrite;
try
FDirCount := Value;
finally
FSync.EndWrite;
end;
end;
end.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.