نمایش نتایج 1 تا 23 از 23

نام تاپیک: استفاده از Thread ها در دلفی ...

  1. #1

    استفاده از Thread ها در دلفی ...

    به نام خدا

    استفاده از Thread ها در دلفی


    اساس کار ویندوز در اجرای برنامه ها بر روی Thread ها است ، هنگامی که برنامه ای اجرا می شود ، کلیه کدها و فایلهای منبع ( Resource ) آن در یک یا چند Thread قرار می گیرند ، درواقع هرProcess در ویندوز دارای یک یا چند Thread است که اطلاعات Process درآنها قرار دارند و بر روی حافظه موقت بارگذاری شده اند ... ، برنامه ها میتوانند در زمان اجرای خود Thread هایی ساخته و سپس آنها را آزاد نمایند ، کار یک Process زمانی به پایان می رسد که تمام ، Thread های آزاد شده باشند ، در غیر این صورت آن Process بسته نخواهد شد ، پس باید در آزادسازی Thread ها دقت زیادی داشت ...

    ساخت Thread و استفاده از آن در برنامه :
    در دلفی کلاسی به نام TThread قرار دارد که امکان استفاده از Thread ها را فراهم می سازد ...
    برای استفاده از یک Thread ابتدا باید یک نسخه از کلاس TThread را Create کرده و سپس از آن استفاده نمایید
    برای ساخت یک Thread به صورت زیر عمل می کنیم :
    Type
    MyThread = Class(TThread)
    private

    protected
    ...
    end;

    در کد بالا یک نوع از TThread را ساختیم ...
    در یک Thread میتوانید Procedure ها و توابعی را قرار داده و از آنها استفاده نمایید ، توجه داشته باشید که برای فراخوانی توابع و متد ها باید از روش Synchronization ( همزمان سازی ) استفاده نمایید ، شاید با دیدن این کلمات احساس کنید که کار سختی در پیش دارید ، اما اصلا این طور نیست ، این کار با اجرای یک تابع ساده امکان پذیر است که در ادامه توضیح خواهیم داد ...
    Thread ها یک Event اصلی به نام OnExecute دارند که مربوط به زمان اجرا شدن آنها است ، تمام کار Thread ها در همین Event انجام می شود ، کدی که در این رویداد می نویسید از زمان اجرا شدن Thread تا زمان Terminate شدن آن اجرا خواهد شد.
    نمی توان در یک Thread به صورت مستقیم با اشیای فرم ارتباط داشت ، چنین درخواستهایی از Thread باعث متوقف شدن کار آن خواهد شد و نتیجه مطلوبی نخواهید گرفت ... ، برای دسترسی به اشیاء باید از Procedure های جدا و Synchronize استفاده نمایید تا اختلالی در کار Thread به وجود نیاید ...
    ابتدا باید توابع و متد ها را در یک Thread تعریف کرده و کد مورد نظر را در آن بنویسیم ، سپس با تابع Synchronize به روش زیر می توانیم آن را اجرا نماییم :
    Synchronize( My Procedure );


    طریقه ایجاد توابع و Procedure ها در Thread مانند سایر کلاسها ( مثلا TForm ) است ، برای مثال فرض کنید متدی داریم که در آن عمل Progress کردن یک ProgressBar را انجام می دهیم ، میتوانیم به صورت زیر این متد را تعریف نماییم :
    Type
    MyThread = Class(TThread)
    private
    procedure doProgress;
    end;

    Implementation

    procedure doProgress;
    begin
    Form1.ProgressBar1.Progress;
    end;


    ساخت و استفاده از Thread :
    در بالا نحوه تعریف یک Thread را توضیح دادیم ، برای استفاده از آن باید یک متغیر با نام Thread تعریف شده تعریف نماییم و از آن استفاده کنیم ...
    نکته دیگر این که متد Create برای Thread ها یک پارامتر به نام Suspended دارد که از نوع Boolean می باشد و به صورت پیشفرض دارای مقدار False است ...
    این پارامتر مشخص میکند که آیا Thread در حالت متوقف ساخته شود یا اینگه بعد از ساخته شدن بلافاصله در حالت اجرا قرار گیرد ( Thread بعد از ساخته شدن ، متد Execute اش اجرا خواهد شد ، با True کردن این پارامتر ، متد Execute را متوقف کرده و از اجرا شدن کدها جلوگیری می نماییم ) ، بعد از اجرای Thread ممکن است نیاز باشد که برخی از خصوصیات آن را تغییر دهیم ، پس باید به این پارامتر مقدار True دهیم تا Thread ما بعد از ساخته شدن در حالت اجرا نباشد و امکان تغییر خاصیتهای آن وجود داشته باشد ...
    برای مثال بهتر است که خاصیت FreeOnTerminate مربوط به Thread ساخته شده را True نماییم تا هنگام فراخوانی متد Terminate برای پایان کار Thread‌ ، آن را آزاد کنیم ...
    پس کد ما تا اینجا به شکل زیر درخواهد آمد :
    var
    T : MyThread;
    begin
    T := MyThread.Create(True);
    T.FreeOnTerminate := True;
    T.Resume;
    end;


    در کد بالا Thread ما ساخته شده و سپس خاصیت FreeOnTerminate آن True شده و سپس با استفاده از متد Resume به کار خود ادامه می دهد ( از حالت Suspend بیرون می آید ) ...

    کد نویسی در رویداد OnExecute :
    هر Thread ای که Create می کنید در حالت پیشفرض رویداد OnExecute را دارا می باشد ، برای این که آن را به دلخواه خود تغییر دهید باید آن را دوباره تعریف کنید ، برای تعریف این رویداد باید از قسمت Protection و وا‍ژه Override استفاده نمایید تا رویداد قبلی Thread از بین رفته و رویداد جدیدی که ایجاد می کنید جایگزین شود ، پس کد شما به این صورت خواهد بود :
    type
    MyThread = Class(TThread)
    private
    ...
    protected
    procedure Execute; override;
    end;

    var

    implementation

    procedure MyThread.Execute;
    begin

    end;


    اجرای Procedure های تعریف شده ( Synchronization ) :
    برای فراخوانی Procedure هایی که تعریف کرده اید باید ار تابع Synchronize استفاده نمایید ( در داخل رویداد OnExecute ) ، برای مثال :
    procedure MyThread.Execute;
    begin
    Synchronize(doProgress);
    end;


    تابع Synchronize یک پارامتر دارد که از نوع TThreadMethod است و Procedure ای که در Thread تعریف کردید باید در آن قرار گیرد ...

    مدیریت Thread :
    برای استفاده از Thread با متدهای آن آشنایی داشته باشید ...
    برای متوقف کردن یک Thread باید از متد Suspend استفاده نمایید ، و برای ادامه کار آن باید از متد Resume استفاده کنید :
    MyThread.Suspend;
    ...
    MyThread.Resume;


    برای این که بفهمید آیا Thread ما در حالت Suspend است یا خیر میتوانید از خاصیت Suspended استفاده نمایید ، این خاصیت یک مقدار Boolean دارد که مشخص می کند Thread مورد نظر Suspend شده یا خیر :
    var
    isSuspended : Boolean;
    begin
    isSuspended := MyThread.Suspended;
    end;


    خاصیت Priority :
    اگر در محیط ویندوز برنامه Task Manager را اجرا نموده و به قسمت Process بروید لیست Process های در حال اجرا را می بینید ، اگر بر روی هر کدام از این Process ها راست کلیک نمایید گزینه ای به نام Set Priority می بینید که مقادیری مثل High‌ ، Normal یا Low و ... دارد ، Priority مشخص می کند که در زمان الویت بندی اجرای Thread ها در CPU ، کدام یک ارجعیت دارند و به CPU ابتدا باید به درخواست کدام یک از آنها جواب دهد ، هرچه مقدار Priority یک Thread مقدار بالاتری داشته باشد ، الویت بیشتری خواهد داشت و عملیاتش زودتر انجام خواهد شد ...
    می توانید برای Threadخود این خاصیت را تنظیم نمایید ، این خاصیت از نوع TThreadPriority می باشد ، در تصویر زیر مقادیری که می توانید به عنوان Priority قرار دهید مشخص شده است :


    ThreadID :
    این خاصیت شناسه ای برای Thread شما است که هم در زمان ساخت ( در زمان Debug‌ ) و هم در زمان اجرای برنامه می توانید از آن استفاده نمایید ، هنگامی که قصد Debug کردن برنامه خود در محیط دلفی را دارید ، پس از اجرا کردن برنامه اگر از منوی View گزینه Debug Windows و سپس گزینه Threads را انتخاب نمایید ، پنجره ای باز شده و لیستی از Thread های در حال اجرا در برنامه شما را نمایش میدهد که هرکدام از آنها دارای شناسه ای به نام ThreadID هستند ، با داشتن این مقدار می توانید Thread مورد نظر خود را در این پنجره پیدا نمایید ...
    این مقدار را می توانید به روش زیر بدست آورید :
    var
    MyThreadID : Cardinal;
    begin
    MyThreadID := MyThread.ThreadID;
    end;



    خروج از Thread و آزاد کردن آن :
    رویداد OnTerminate :
    Thread یک رویداد دیگر دارد که میتوانید آن را مانند OnExecute تنظیم نمایید و تغییر دهید ، این رویداد زمانی اتفاق می افتد که Thread مورد نظر Terminate‌ شود ، اما متد دیگری به نام DoTerminate وجود دارد که این رویداد را اجرا میکند بدون اینکه Thread مورد نظر Terminate شود ( یا شده باشد ) ، با متد ...

    ---------

    اگر یادتان باشد ،‌ ما در هنگام ساخت Thread مقدار خاصیت FreeOnTerminate‌آن را True کردیم پس اگر آن را Terminate نماییم ، آزاد ( Free ) خواهد شد ، با متد Terminate میتوانید به کار یک Thread پایان دهید :
    MyThread.Terminate;


    در برخی موارد ممکن است Thread مورد نظر Terminate نشود ! ، درواقع هنگامی که ما متد Terminate را اجرا می کنیم ، کار عمده ای انجام نمی شود ، بلکه فقط خاصیت Terminated مربوط به Thread بر روی True تنظیم می شود ! ، درواقع این عمل به Thread اعلام میکند که به زودی ممکن است کارش پایان یابد ، باید برای پایان کار Thread‌ ، بعد از اجرا این متد با استفاده از متد Exit ( مربـوط به Thread نیست ) از رویداد OnExecute خارج شد ( دستور Exit در دلفی برای خروج از یک رویه ( تابع یا ... ) به کار می رود ) :
    procedure MyThread.Execute;
    begin
    Synchronize(doProgress);

    MyThread.Terminate;
    Exit;
    end;


    توجه داشته باشید که در قسمتهای مختلف کد باید چک کنید که آیا Terminated مربوط به Thread مقدار True دارد یا خیر و اگر مقدار True داشت با استفاده از دستور Exit از رویداد خارج شوید :
    procedure MyThread.Execute;
    begin
    if MyThread.Terminated then
    Exit;

    if MyThread.Terminated then
    Exit;

    MyThread.Terminate;
    Exit;
    end;


    علاوه بر موارد بالا می توانید از متد WaiteFor استفاده نمایید ، متد WaiteFor تا زمانی که کار Thread‌ به پایان برسد کارش تمام نخواهد شد ، درواقع می توانید کد Exit را بعد از این متد بنویسید تا خیالتان از بابت پایان کار Thread راحت شود ! :
    procedure MyThread.Execute;
    begin
    if MyThread.Terminated then
    Exit;

    if MyThread.Terminated then
    Exit;

    MyThread.Terminate;
    MyThread.WaiteFor;
    Exit;
    end;


    پایان ...


    امیدوارم مفید بوده باشه ...

    PDF این مقاله رو می تونید از اینجا دانلود کنید ...

    موفق باشید ...
    آخرین ویرایش به وسیله Mahmood_M : جمعه 10 آبان 1387 در 15:25 عصر

  2. #2
    کاربر دائمی آواتار shervin farzin
    تاریخ عضویت
    مرداد 1387
    محل زندگی
    مشهد - shervinfarzin@gmail.com
    پست
    256

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    با سلام

    آقا يه سوال . من با delphi 2007 كار ميكنم و براي thread كه تعريف كردم هيچ Propertie يا تابعي به نام Stop نميبينم . مشكلم از چيه ؟

    ممنون

  3. #3

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    براي thread كه تعريف كردم هيچ Propertie يا تابعي به نام Stop نميبينم . مشكلم از چيه ؟
    کلاس TThread متدی بنام Stop نداره. برای متوقف کردن یک Thread از داخل یک Thread دیگه، 3 راه دارید:
    1- Thread را با استفاده از متد Suspend معلق کنید.
    2- Thread را با استفاد از تابع TerminateThread متوقف کنید؛ این روش یک نوع توقف اضطراری هست، نه توقف طبیعی.
    3- متد Terminate از TThread را اجرا کنید، یا خصوصیت Terminated آن را True کنید. متد Terminate به خودی خود کاری انجام نمیده، فقط Terminated را True میکنه. از طرفی True کردن Terminated باعث توقف Thread نمیشه، بلکه Thread باید مرتبا در کدی که توسط متد Execute اجرا میشه، بررسی کنه که آیا Terminated برابر True شده یا نه، اگر شده، اجرای متد Execute را پایان بده. پایان یافتن متد Execute موجب متوقف شدن Thread میشه.
    البته دقت کنید که متوقف شدن Thread به معنی آزاد شدن شی آن نیست، بلکه یا باید خصوصیت FreeOnTerminate را True کنید تا بعد از متوقف شدن Thread، شی آن آزاد هم بشه، یا خودتان متد Free را فراخوانی کنید.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  4. #4
    کاربر دائمی آواتار shobair
    تاریخ عضویت
    فروردین 1387
    محل زندگی
    تهران
    سن
    43
    پست
    339

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    سلام

    زمانی که یک Thread ایجاد میکنیم اگر لازم باشه از متدها یا اشیای برنامه اصلی استفاده بشه باید حتماً کد مورد نظر در یک پروسیجر یا تابع نوشته بشه و سپس اون رو توسط متد Syncronize صدا بزنیم. این نکته ای هستش که ادیتور دلفی موقع ایجاد یک Thread Object به صورت کامنت بهش اشاره میکنه:
    { Important: Methods and properties of objects in VCL or CLX can only be used
    in a method called using Synchronize, for example,

    Synchronize(UpdateCaption);

    and UpdateCaption could look like,

    procedure myTred.UpdateCaption;
    begin
    Form1.Caption := 'Updated in a thread';
    end; }
    احتمالاً این به منظور Safe بودن Thread گفته شده ولی سوال اینجاست که پس چرا انجام این کار تا حدودی باعث قفل شدن برنامه اصلی میشه و در واقع مقصود اصلی از بکارگیری Thread رو برآورده نمیکنه؟
    برای اینکه این بتونید منظورم رو بفهمید کافیه داخل Thread تابعی مثل Sleep رو استفاده کنید و بعد از صدا زدن Thread در برنامه اصلی یک ShowMessage بکار ببرید تا ببینید چی میشه.
    اتفاقی که میوفته اینه که پنجره ی دستور ShowMessage باز میشه ولی داخلش دکمه ی OK و متن وجود نداره! تا زمانی که اجرای Thread به پایان برسه.

    اگه نخواهیم اینجوری بشه باید چکار کرد؟

    ممنون
    شبیر

  5. #5

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    اگه نخواهیم اینجوری بشه باید چکار کرد؟
    اگر توی همین بخش Synchronize را جستجو می کردید، به جوابتون می رسیدید.

    بطور خلاصه، متد Synchronize یک روش ابتدایی برای همزمان سازی Threadها هست. در این روش، موقع اجرای متد، Thread مورد نظر متوقف میشه، و تابع مورد نظر توسط Synchronize در Context مربوط به Thread اصلی اجرا میشه. یعنی عملا در لحظه اجرای کد مربوطه توسط Synchronize دو Thread که بصورت موازی در حال اجرا بودند، بصورت سری (پشت سر هم) اجرا میشند. برای همین هم Synchronize فقط بدرد همزمان سازی های ساده میخوره.

    برای کارهای پیچیده تر، یا کارهایی که نیاز به کارایی بالاتری دارند، باید از روش های دیگه ایی استفاده کرد. مثلا برای بروز رسانی رابط کاربر، ارسال پیام به Thread اصلی که مسئولیت بروز کردن رابط کاربر را داره، بهترین گزینه هست، چون نه Thread مورد نظر متوقف میشه، نه Thread اصلی نیاز داره کار فعلی خودش را متوقف کنه و بالافاصله درخواست Thread شماره 2 را اجرا کنه. پیام میره به صف پیام های Thread اصلی و Thread اصلی آن را پردازش میکنه. Thread شماره 2 هم بعد از ارسال پیام نیازی نداره منتظر باشه، بکارش ادامه میده.

    درباره اینکه چرا باید رابط کاربر همیشه از طریق Threadایی که آن را بوجود آورده، تغییر داده بشه هم توضیح داده شد، و گفته شد که این یکی از ضروریاتی هست که Win32 اعمال میکنه.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  6. #6
    کاربر دائمی آواتار shobair
    تاریخ عضویت
    فروردین 1387
    محل زندگی
    تهران
    سن
    43
    پست
    339

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    برای کارهای پیچیده تر، یا کارهایی که نیاز به کارایی بالاتری دارند، باید از روش های دیگه ایی استفاده کرد. مثلا برای بروز رسانی رابط کاربر، ارسال پیام به Thread اصلی که مسئولیت بروز کردن رابط کاربر را داره، بهترین گزینه هست، چون نه Thread مورد نظر متوقف میشه، نه Thread اصلی نیاز داره کار فعلی خودش را متوقف کنه و بالافاصله درخواست Thread شماره 2 را اجرا کنه. پیام میره به صف پیام های Thread اصلی و Thread اصلی آن را پردازش میکنه. Thread شماره 2 هم بعد از ارسال پیام نیازی نداره منتظر باشه، بکارش ادامه میده.
    سلام
    ممنون ولی این کاری که گفتید رو چطوری میتونم یاد بگیرم و انجام بدم؟ قبلاً در موردش صحبت شده یا نه؟ چه مرجعی پیشنهاد می کنید؟

    شبیر

  7. #7

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    ممنون ولی این کاری که گفتید رو چطوری میتونم یاد بگیرم و انجام بدم؟
    متناسب با نوع کار Thread تان یک یا چند Message جدید تعریف می کنید، مثلا:

    const
    TM_MYTHREAD_MSG = WM_USER + 200;
    TM_MYTHREAD_START = TM_MYTHREAD_MSG + 1;
    TM_MYTHREAD_PROGRESS = TM_MYTHREAD_MSG +2;
    TM_MYTHREAD_DONE = TM_MYTHREAD_MSG +3;
    بعد در داخل کد Threadتان هر جا که لازم بود، این پیام ها را با استفاده از PostMessage به Thread اصلی می فرستید (مثلا به فرم اصلی برنامه یا به هر پنجره دیگه ایی)، مثلا:

    PostMessage(FormHandle, TM_MYTHREAD_MSG, TM_MYTHREAD_START,0);
    در Thread اصلی، یک Message Handler برای این پیام ها می نویسید و پیام را در آن پردازش می کنید، مثلا:

    TMyForm = class(TForm)
    ...
    protected
    procedure TmMyThreadMsg(var Msg: TMessage); message TM_MYTHREAD_MSG;
    ...
    end;

    ----

    procedure TMyForm.TmMyThreadMsg(var Msg: TMessage);
    begin
    case Msg.LParam of
    TM_MYTHREAD_START : Progressbar1.Position := 0;
    TM_MYTHREAD_PROGRESS : Progressbar1.Position := Progressbar1.Position + 1;
    TM_MYTHREAD_DONE : Progressbar1.Position := Progressbar1.Max;
    end;
    end;

    آخرین ویرایش به وسیله vcldeveloper : جمعه 10 آبان 1387 در 10:47 صبح دلیل: تصحیح Message Handle به Message Handler


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  8. #8

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    استفاده از Thread ها در دلفی
    حاجی قربون دستت، بازهم ادامه بده.

  9. #9
    کاربر دائمی
    تاریخ عضویت
    آبان 1386
    محل زندگی
    تهران
    پست
    159

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    روش استفاده از terminateو ... که توضیح داده شده برای مواقعی که به صورت زیر استفاده شود

    var
    T : MyThread;
    begin
    try
    T := MyThread.Create(True);
    T.FreeOnTerminate := True;
    T.Resume;
    finally
    t.terminate
    end;


    (ببخشید کدها دقیق نیستن) یعنی یک thread در یک متد فراخوانی و اجرا و terminate بشه. اگر لازم باشد که یک thread خاص در یک پروسه دیگر terminate بشه چطور؟ تا جایی که من میدونم یه thread فقط در زمان اجرا یه id داره که اونم تغییر می کنه

  10. #10

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    اگر لازم باشد که یک thread خاص در یک پروسه دیگر terminate بشه چطور؟
    هر Thread متعلق به یک Process هست. در منطق ویندوز هم Process ها از هم ایزوله هستند. پس مکانیزم آماده ایی برای کنترل یک Thread از طریق یک Process دیگه ارائه نمیشه. برای بستن اضطراری Threadها در ویندوز تابع TerminateThread ارائه شده که نیاز به هندل Thread مورد نظر داره.

    تا جایی که من میدونم یه thread فقط در زمان اجرا یه id داره که اونم تغییر می کنه
    ID یک Thread در زمان اجرای آن ثابت هست، و تغییر نمیکنه.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  11. #11

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    نقل قول نوشته شده توسط علی کشاورز مشاهده تاپیک
    متناسب با نوع کار Thread تان یک یا چند Message جدید تعریف می کنید، مثلا:

    const
    TM_MYTHREAD_MSG = WM_USER + 200;
    TM_MYTHREAD_START = TM_MYTHREAD_MSG + 1;
    TM_MYTHREAD_PROGRESS = TM_MYTHREAD_MSG +2;
    TM_MYTHREAD_DONE = TM_MYTHREAD_MSG +3;
    بعد در داخل کد Threadتان هر جا که لازم بود، این پیام ها را با استفاده از PostMessage به Thread اصلی می فرستید (مثلا به فرم اصلی برنامه یا به هر پنجره دیگه ایی)، مثلا:

    PostMessage(FormHandle, TM_MYTHREAD_MSG, TM_MYTHREAD_START,0);
    در Thread اصلی، یک Message Handler برای این پیام ها می نویسید و پیام را در آن پردازش می کنید، مثلا:

    TMyForm = class(TForm)
    ...
    protected
    procedure TmMyThreadMsg(var Msg: TMessage); message TM_MYTHREAD_MSG;
    ...
    end;

    ----

    procedure TMyForm.TmMyThreadMsg(var Msg: TMessage);
    begin
    case Msg.LParam of
    TM_MYTHREAD_START : Progressbar1.Position := 0;
    TM_MYTHREAD_PROGRESS : Progressbar1.Position := Progressbar1.Position + 1;
    TM_MYTHREAD_DONE : Progressbar1.Position := Progressbar1.Max;
    end;
    end;

    با سلام خدمت اقاي كشاورز و ديگر دوستان

    اقاي كشاورز من به يك نكته برخورد كردم !!

    شما يك جا گفتيد :

    بعد در داخل کد Threadتان هر جا که لازم بود، این پیام ها را با استفاده از PostMessage به Thread اصلی می فرستید (مثلا به فرم اصلی برنامه یا به هر پنجره دیگه ایی)، مثلا:

    خب فرض كنيد ما دو تا برنامه ايجاد كرديم كه اصلا هيچ فرمي ندارن و در اونها هم از Thread ها استفاده كرديم .. حالا ميخواييم بين اون دو تا برنامه با تعريف يك سري Message خاص ارتباط برقرار كنيم .... حالا كه هيچ پنجره اي نيست ما چه جوري بايد اين پيغام ها رو بين Thread هاي دو برنامه پاس كاري كنيم ؟؟؟ فرض كنيم ميخواييم هر دو تا Thread هم بتونن براي هم پيغام بفرستن هم بتونن پيغامهاي هم رو بگيرن و پردازش كنن ... ميشه يكم در اين زمينه هم توضيح بدين ....

  12. #12

    نقل قول: مقاله : استفاده از Thread ها در دلفی ...

    خب فرض كنيد ما دو تا برنامه ايجاد كرديم كه اصلا هيچ فرمي ندارن و در اونها هم از Thread ها استفاده كرديم .. حالا ميخواييم بين اون دو تا برنامه با تعريف يك سري Message خاص ارتباط برقرار كنيم .... حالا كه هيچ پنجره اي نيست ما چه جوري بايد اين پيغام ها رو بين Thread هاي دو برنامه پاس كاري كنيم ؟؟؟ فرض كنيم ميخواييم هر دو تا Thread هم بتونن براي هم پيغام بفرستن هم بتونن پيغامهاي هم رو بگيرن و پردازش كنن ... ميشه يكم در اين زمينه هم توضيح بدين ....
    اون روش برای بروزرسانی رابط کاربر بود. در سناریویی که شما مطرح کردید، رابط کاربری برای بروز شدن وجود نداره، بلکه فقط Threadها باید به نوعی با هم همزمان بشند. برای این کار روش های مختلفی وجود داره، مثل استفاده از CriticalSection, Mutex, Semaphore, Event و... که کلا در ویندوز به عنوان Synchronization Objects شناخته میشند.
    اگر واقعا Threadهای شما نیاز دارند که بصورت Asynchronous برای هم پیام هایی صادر کنند، اون وقت می تونید با استفاده از AllocateHWnd یک پنجره مخفی برای Threadهاتون درست کنید و باهاش پیام های دریافتی را پردازش کنید. البته درباره Thread-Safe نبودن AllocateHWnd در این صفحه توضیحاتی داده شده، و راه حلی هم ارائه شده:
    http://17slon.com/blogs/gabr/2007/06...read-safe.html

    درباره کاربرد خودِ AllocateHWnd هم می تونید این صفحه را ببینید:
    http://www.delphidabbler.com/articles?article=1


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  13. #13

    نقل قول: استفاده از Thread ها در دلفی ...

    سلام بر همه دوستان و اساتید.
    ببخشید که من این تاپیک رو بعد از یک سال و نیم دوباره بالا میارم. فکر کردم مطالب مربوط به thread ها اگه در یک جا متمرکز باشه مفیدتره.
    در برنامه من در اولین فرم، اطلاعات اتصال به دو بانک (یکی لوکال و دیگری هاست) از یوزر گرفته میشه و بعد از کلیک بر روی دکمه تایید، یه فرم خوشامد گویی ظاهر میشه. روی این فرم خوشامدگویی، یک label هست (labelstatus) که مرحله به مرحله وضعیت اتصال به بانک رو نمایش میده. در واقع این فرم خوشامدگووی برای اینه که در پس زمینه برنامه به بانک روی هاست کانکت بشه. مشکل اینجاست که من از thread ها استفاده کردم تا وقتی که برنامه مشغول ارتباط با بانک روی هاسته فرم خوشامد گویی قفل نشه ولی فرم قفل میشه و بعد از کانکت شدن آزاد میشه. من کدی رو که نوشتم قرار میدم، دوستان عزیز اگر راهنمایی کنید ممنون میشم.

    کد یونیت مربوط به thread :

    unit Unit12;

    interface
    uses
    classes,stdctrls,sysutils,Myclasses, Mycall, windows;

    type
    InitializeThread = class(TThread)
    private
    i:integer;
    ss:string;
    procedure setlabel;
    procedure localdbconnect;
    procedure hostdbconnect;
    procedure settingvalues;
    procedure settingqueries;

    public
    //------------
    protected
    procedure execute; override;

    end;

    implementation

    uses unit1,unit2,unit3,unit4;
    //-------------------------------------------------------------------
    procedure InitializeThread.setlabel;
    begin
    WelcomeForm.LabelStatus.Caption:=ss;
    end;
    //-------------------------------------------------------------------
    procedure InitializeThread.settingvalues;
    begin

    DataModule1.MyConnection_Host.Database:=LoginForm. sEdit4.Text;
    DataModule1.MyConnection_Host.Password:=LoginForm. sEdit6.Text;
    DataModule1.MyConnection_Host.Username:=LoginForm. sEdit5.Text;
    DataModule1.MyConnection_Host.Server:=LoginForm.sE dit3.Text;

    DataModule1.MyConnection_Local.Database:=LoginForm .sEdit8.Text;
    DataModule1.MyConnection_Local.Password:=LoginForm .sEdit10.Text;
    DataModule1.MyConnection_Local.Username:=LoginForm .sEdit9.Text;
    DataModule1.MyConnection_Local.Server:=LoginForm.s Edit7.Text;
    end;
    //-------------------------------------------------------------------
    procedure InitializeThread.localdbconnect;
    begin

    try
    DataModule1.MyConnection_Local.Connect;
    except
    on e:EMyError do
    begin
    if e.ErrorCode = 1045 then MessageBox(Handle,'.äÇã ˜ÇÑÈÑí íÇ ˜áãå ÚÈæÑ Ïæã ÇÔÊÈÇå ÇÓÊ','!ÎØÇ',MB_OK+MB_ICONERROR);
    if e.ErrorCode = 2003 then MessageBox(Handle,'.ÂÏÑÓ íÇ äÇã ÓÑæÑ Ïæã ÇÔÊÈÇå ÇÓÊ','!ÎØÇ',MB_OK+MB_ICONERROR);
    if e.ErrorCode = 1049 then MessageBox(Handle,'.äÇã ÈÇä˜ ÇØáÇÚÇÊí Ïæã ÇÔÊÈÇå ÇÓÊ','!ÎØÇ',MB_OK+MB_ICONERROR);
    if e.ErrorCode = 2013 then MessageBox(Handle,'.ÊáÇÔ ÈÑÇí ÇÑÊÈÇØ ÈÇ ÓÑæÑ Ïæã ÈíÔ ÇÒ ÍÏ ãÞÑÑ Èå Øæá ÇäÌÇãíÏ','!ÎØÇ',MB_OK+MB_ICONERROR);
    end;
    end; //local except

    end;
    //-------------------------------------------------------------------
    procedure InitializeThread.hostdbconnect;
    begin

    try
    DataModule1.MyConnection_Host.Connect;
    except
    on e:EMyError do
    begin
    if e.ErrorCode = 1045 then MessageBox(Handle,'.äÇã ˜ÇÑÈÑí íÇ ˜áãå ÚÈæÑ Çæá ÇÔÊÈÇå ÇÓÊ','!ÎØÇ',MB_OK+MB_ICONERROR);
    if e.ErrorCode = 2003 then MessageBox(Handle,'.ÂÏÑÓ íÇ äÇã ÓÑæÑ Çæá ÇÔÊÈÇå ÇÓÊ','!ÎØÇ',MB_OK+MB_ICONERROR);
    if e.ErrorCode = 1049 then MessageBox(Handle,'.äÇã ÈÇä˜ ÇØáÇÚÇÊí Çæá ÇÔÊÈÇå ÇÓÊ','!ÎØÇ',MB_OK+MB_ICONERROR);
    if e.ErrorCode = 2013 then MessageBox(Handle,'.ÊáÇÔ ÈÑÇí ÇÑÊÈÇØ ÈÇ ÓÑæÑ Çæá ÈíÔ ÇÒ ÍÏ ãÞÑÑ Èå Øæá ÇäÌÇãíÏ','!ÎØÇ',MB_OK+MB_ICONERROR);
    end;
    end; //host except

    end;
    //-------------------------------------------------------------------
    procedure InitializeThread.settingqueries;
    begin
    DataModule1.MyQuery_Local1.Close;
    DataModule1.MyQuery_Local1.SQL.Text:='select count(*) as row_c_l from products';
    DataModule1.MyQuery_Local1.Open;

    DataModule1.MyQuery_Host1.Close;
    DataModule1.MyQuery_Host1.SQL.Text:='select count(*) as row_c_h from products';
    DataModule1.MyQuery_Host1.Open;

    { if DataModule1.MyQuery_Local1.FieldValues['row_c_l']=DataModule1.MyQuery_Host1.FieldValues['row_c_h'] then
    ShowMessage('equal') else ShowMessage('unequal');
    }

    end;

    //-------------------------------------------------------------------
    procedure InitializeThread.execute;
    begin
    ss:='Setting databases connection values.';
    Synchronize(setlabel);
    Synchronize(settingvalues);

    ss:='Connecting local database...';
    Synchronize(setlabel);
    Synchronize(localdbconnect);

    ss:='Connecting host database...';
    Synchronize(setlabel);
    Synchronize(hostdbconnect);

    ss:='Comparing local and remote databases...';
    Synchronize(setlabel);
    Synchronize(settingqueries);

    Terminate;
    Exit;

    end;
    //-------------------------------------------------------------------

    end.
    کد مربوط به فراخوانیش :

    procedure TLoginForm.sBitBtn1Click(Sender: TObject);
    var
    myTH : InitializeThread;
    begin
    WelcomeForm.Show;

    try
    myTH:=InitializeThread.Create(true);
    myTH.FreeOnTerminate:=true;
    myTH.Resume;
    except
    on e:Exception do ShowMessage(e.Message);
    end;

    end;
    با کلیک بر روی دکمه ای که در بالا رویداد onclick ش رو نوشتم فرم welcome نمایش داده میشه و بعد thread اجرا میشه. اما نتیجه خوب نیست. فقط وقتی که بانک روی هاست کانکت میشه، فرم از حالت قفل خارج میشه. پیشاپیش از راهنمایی شما ممنون.

    پویا.

  14. #14
    کاربر دائمی آواتار 1485159
    تاریخ عضویت
    فروردین 1388
    محل زندگی
    NULL
    سن
    30
    پست
    886

    نقل قول: استفاده از Thread ها در دلفی ...

    ببخشید میخواستم ببینم که یه ترد به چه دردی میخوره؟؟یه سوال دیگه مگه شما نگفتید که در رویاداد Execute هر دسوری بنویسی تا زمانی که ترد آزاد بشه اون دستور اجرا میشه؟
    پس چرا فقط یک بار اجرا میشه؟؟ و بعد ترد آزاد میشه؟
    ممنون
    unit Unit1;
    interface
    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;
    type
    TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    private
    public
    end;
    Type
    MyThread = Class(TThread)
    private
    protected
    procedure Execute; override;
    end;
    var
    Form1: TForm1;
    implementation
    {$R *.dfm}
    ////
    procedure MyThread.Execute;
    begin
    form1.Caption:=form1.Caption+'1';
    end;
    ////
    procedure TForm1.FormCreate(Sender: TObject);
    var
    T : MyThread;
    begin
    T := MyThread.Create(True);
    T.FreeOnTerminate := true;
    T.Resume;
    end;
    end.

  15. #15

    Smile نقل قول: استفاده از Thread ها در دلفی ...

    سلام
    1-حتما Thread بايد در يك يونيت جدا تعريف بشه؟
    2-اگر جواب سؤال 1 منفي است چه فرقي مي كنه كه جداگانه تعريف شود يا نشود آيا هر كدام مزايا و معايبي دارند؟

    با تشكر

  16. #16

    Smile نقل قول: استفاده از Thread ها در دلفی ...

    سلام دوست عزيز Thread وقتي كارش به پايان رسيد خود به خود متوقف ميشه فقط با دستور
    Freeonterminate مي تونيم بعد از توقفش اون رو آزاد كنيم.

    موفق باشي

  17. #17

    نقل قول: استفاده از Thread ها در دلفی ...

    1-حتما Thread بايد در يك يونيت جدا تعريف بشه؟
    خیر
    2-اگر جواب سؤال 1 منفي است چه فرقي مي كنه كه جداگانه تعريف شود يا نشود آيا هر كدام مزايا و معايبي دارند؟
    از نظر کارایی هیچی؛ ولی از نظر نگهداری کد، اگر کدهای مربوط به هر موضوع در یونیت های مخصوص به خودشان نگهداری شوند، بهتر از این هست که کدهای چند موضوع مختلف که ارتباط چندانی هم با هم ندارند، در یک یونیت جمع شوند.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  18. #18

    نقل قول: استفاده از Thread ها در دلفی ...

    من از Thread استفاده می کنم یه پروسیجرم دارم که یه حلقه بینهایت که با تابع Synchronize با thread همزمان سازی شده وقتی از thread استفده میکنم برنامه هنگ می کنه می خواستم بدونم دلیلش چیه مگه thread برای پردازش موازی نسیت؟!!

  19. #19

    نقل قول: استفاده از Thread ها در دلفی ...

    من از Thread استفاده می کنم یه پروسیجرم دارم که یه حلقه بینهایت که با تابع Synchronize با thread همزمان سازی شده وقتی از thread استفده میکنم برنامه هنگ می کنه می خواستم بدونم دلیلش چیه مگه thread برای پردازش موازی نسیت؟!!
    دلیل هنگ کردن برنامه می تونه این باشه که مثلا از داخل بدنه ی Thread خواستید به یک شی دسترسی مستقیم داشته باشید ، مطمئن بشید که همچین مشکلی وجود نداره ، دسترسی به اشیاء برنامه باید در یک Procedure جدا و به وسیله ی Synchronize انجام بشه ...

    موفق باشید ...

  20. #20
    کاربر تازه وارد آواتار BEHESHT*
    تاریخ عضویت
    مهر 1388
    محل زندگی
    گلزار شهدای گمنام
    پست
    66

    Smile نقل قول: استفاده از Thread ها در دلفی ...

    لنیک دانلود PDF مربوطه خراب شده ممکنه دوباره قرارش بدین

  21. #21

    نقل قول: استفاده از Thread ها در دلفی ...

    با عرض سلام و احترام خدمت همه دوستان گرامی
    من یک برنامه نوشتم که در آن سه تا Thraed استفاده شده است
    Thread اول برای خواندن دیتا از پورت سریال 1
    Thraed دوم برای خواندن دیتا از پورت سریال 2
    Thread سوم برای خواندن دیتا از کارت شبکه

    تعریف thread ها به صورت زیر می باشد


    var
    Sr1Thrd:TSerialThread;
    Sr2Thrd:Tserial2Thread;
    LanThrd:TlanThread;

    هر سه تا Thread هم تعریف شده اند

    توابع ساخت و اجرای Thread ها را به صورت زیر نوشتم:

    procedure KillThrad1;
    begin
    if Assigned (Sr1Thrd) then
    begin
    TerminateThread(Sr1Thrd.Handle,0)
    FreeandNil(Sr1Thrd);
    end;
    end;



    Procedure TForm1.CreateThrd1;
    begin
    KillThrad1;
    Sr1Thrd1:=TSerialThread.Create(False);
    end;

    تابع اولی برای اتمام Thread و دومی برای ساخت Thread استفاذه شده است
    چون Thread منتظر می ماند تا از پورت سریال دیتا بگیرد بنا براین با متد Terminate نمی توانم Thread را از بین ببرم به خاطر آن تابع KillThrd1 را نوشتم
    برای دوتا Thread بعدی هم توابعی مثل توابع فوق نوشتم

    در فرم اصلی برنامه یک تایمر گذاشتم که هر 2 ثانیه چک کنه اگه Thread ها دیتا نگرفتن Thread ها را بکشه و دوباره Create کنه کد تایمر به صورت زیر است:

    procedure TForm1.Timer2Timer(Sender: TObject);
    begin
    inc(SocketInterval);
    if(SocketInterval>=5) then
    begin
    SocketInterval:=0;
    closesocket(My_socket);
    CreateLanThread;
    end;

    inc(ComInterval2);
    if (ComInterval2>=5) then
    begin
    ComInterval2:=0;
    CreateSensorThread;
    end;

    inc(ComInterval);
    if (ComInterval>=5) then
    begin
    ComInterval:=0;
    CreateSerialThread;
    end;
    end;


    اگر thread ها دیتا بگیرند هرکدام بترتیب یکی از متغیرهای ComIntervalوComInterval2وSocketInterval را صفر می کنند و تایمر Thread مربوطه را حذف و دوباره نمی سازد
    اینتروال تایمر 1 ثانیه است
    این برنامه بعد از یک ساعت کار کردن Error Not Enugh Storage To create Threadرا می دهد
    دوستان اگر کمک کنند ممنون میشم

  22. #22

    نقل قول: استفاده از Thread ها در دلفی ...

    دوستان کسی کمک نمی کنه؟

  23. #23

    نقل قول: استفاده از Thread ها در دلفی ...

    میگم این لینک دانلود خرابه ها

تاپیک های مشابه

  1. اجرای تابع با پارامتر به صورت یک Thread.
    نوشته شده توسط hdv212 در بخش C#‎‎
    پاسخ: 16
    آخرین پست: یک شنبه 17 خرداد 1394, 00:11 صبح
  2. پیاده سازی تایمر با استفاده از Thread
    نوشته شده توسط Ghasem Dehghani در بخش C#‎‎
    پاسخ: 18
    آخرین پست: شنبه 15 اردیبهشت 1386, 17:40 عصر
  3. ایجاد thread
    نوشته شده توسط mahtab_18 در بخش C#‎‎
    پاسخ: 1
    آخرین پست: سه شنبه 11 اردیبهشت 1386, 09:59 صبح

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •