PDA

View Full Version : دریافت نتیجه Thread !



مهران رسا
شنبه 08 خرداد 1389, 13:28 عصر
سلام ؛

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

lord_viper
شنبه 08 خرداد 1389, 13:59 عصر
با استفاده از CreateFileMapping و MapViewOfFile و OpenFileMapping



const
MemMapFile = 'X_simple';
type
PDLLGlobal = ^TDLLGlobal;
TDLLGlobal = packed record
Handle: HWND;
end;

var
GlobalData: PDLLGlobal;
MMF: THandle;

MMF:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0,
SizeOf(TDLLGlobal), MemMapFile);
GlobalData:= MapViewOfFile(MMF, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TDLLGlobal));

GlobalData^.Handle :=form1.handle;

با این روش میتونین یک متغییر رو بین پروسه ها هم share کنید بعد از ایجاد یک FileMap در هر برنامه ای با Open کردن اون fileMap در هر برنامه ای میتونین به محتویاتش دسترسی داشته باشید

vcldeveloper
شنبه 08 خرداد 1389, 14:53 عصر
گاهی اوقات Threadها نیاز دارند که در حین کار، با هم تعامل داشته باشند، مثلا داده هایی را با هم به اشتراک بگذارند، یا در مرحله ایی از کار، یک یا چند Thread منتظر یک یا چند Thread دیگه باشند. به اشتراک گزاری این داده ها میتونه به شکل های مختلفی رخ بده، مثلا به اشتراک گزاری بخشی از حافظه بین چند Thread، یا به اشتراک گزاری یک فایل بین آنها، و غیره. وقتی بحث دسترسی به داده های اشتراکی بین چند Thread پیش میاد، یک موضوع دیگه پر رنگ میشه، اون هم نحوه دسترسی Threadهای مختلف به اون داده اشتراکی هست؛ برای کنترل دسترسی به داده های اشتراکی بین Threadها از تکنیک هایی با عنوان Synchronization Techniques بهره گرفته میشه. برای انجام این کار، سیستم عامل ها و زبان های برنامه نویسی ابزارهایی را ارائه می کنند، مثلا سیستم عامل شما اشیائی مثل Critical Sections, Mutex, Semaphore, و Events را برای این منظور به شما ارائه میکنه.

البته، اگر Threadهای شما Message Queue دارند (مثلا Thread اصلی برنامه شما)، و هدف شما هم فقط اطلاع رسانی باشه؛ مثلا Threadایی اعلام میکنه که فلان کار انجام شد، یا به فلان مرحله از کار رسید، می تونید از ارسال Message برای اطلاع به سایر Threadها استفاده کنید.

Saeed_m_Farid
شنبه 08 خرداد 1389, 15:38 عصر
چه راهی پیشنهاد میکنید ؟
من با استفاده از ویندوز پروسیجر، این کار رو میکنم، که قبلاً هم کدش رو گذاشتم.
با استفاده از PostMessage و تعریف یه ثابت مثلاً WM_USER + 100 که message شما رو مشخص میکنه و در ویندوز پروسیجر شما همون ثابت (سراسری) رو مدیریت می کنید، در تابع PostMessage شما میتونید دوتا (یا بیشتر از طریق ساختار و اشاره گر و ...) مقدار wParam و lParam رو با دادن هندل فرم، به تابع اصلی بفرسیتد. میدونم انشاء خوب نشد ولی سعی ام رو کردم درست توضیح بدم! مثلاً من تو کد زیر، دو نوع پیام تعریف کردم که یکی عدد و دیگری رشته رو به تابع اصلی من پاس میدن و از lParam هم بعنوان نوع پیغام (مثلاً info، Warning و سایر موارد) استفاده کردم :



const
TH_EVENT_OUT_MESSAGE1 = WM_USER + 101;
TH_EVENT_OUT_MESSAGE2 = WM_USER + 102;



PostMessage(frmMain.Handle, TH_EVENT_OUT_MESSAGE1, iMyInt, iLogType);
PostMessage(frmMain.Handle, TH_EVENT_OUT_MESSAGE2, sMyString, iLogType);



(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

procedure TfrmMain.wndproc(var wndMsg: TMessage);
var
p: PChar;
begin
try
case wndMsg.Msg of

TH_EVENT_OUT_MESSAGE1:begin
// do something with wndMsg.wParam and wndMsg.lParam
Addlog(wndMsg.wParam,TLogType(wndMsg.lParam));
end;

TH_EVENT_OUT_MESSAGE2:begin
p := PChar(wndMsg.wParam);
if p <> nil then begin
// Addlog is a logging function ...
Addlog(p,TLogType(wndMsg.lParam));
FreeMem(p);
end;
end;

else inherited;
end;
except on exp:Exception do
// Addlog is a logging function in my project, you can use ShowMessage ...
Addlog('Exception on wndproc['+IntToStr(wndMsg.Msg)+']: '+exp.Message, ltError);
end;
end;

(*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)



من پست آقای کشاورز رو دیر دیدم، کاش 1 اخطار میداد وی بولتین! بازم شاید بدرد دوستان بخوره ...

مهران رسا
شنبه 08 خرداد 1389, 16:36 عصر
با توجه به نیازی که داشتم به هر حال با یک Do While مشکل حل شد . با تشکر از همه بزرگواران .