ورود

View Full Version : اشکال در برنامه نویسی Thread



mahdy.asia
یک شنبه 11 مرداد 1394, 14:28 عصر
من کد زیر را می خواهم در یک thread بنویسم، کد بدون خطا اجرا می شود اما هنگام اجرا کار دیگری نمی شود انجام داد و انگاری کد بدون thread اجرا شده است.

procedure SplitFile(FileName : TFileName; FilesByteSize : Integer) ;
// FileName == file to split into several smaller files
// FilesByteSize == the size of files in bytes
var
fs, ss: TFileStream;
cnt : integer;
SplitName: String;
begin
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite) ;
try
for cnt := 1 to Trunc(fs.Size / FilesByteSize) + 1 do
begin
SplitName := ChangeFileExt(FileName, Format('%s%d', ['._',cnt])) ;
ss := TFileStream.Create(SplitName, fmCreate or fmShareExclusive) ;
try
if fs.Size - fs.Position < FilesByteSize then
FilesByteSize := fs.Size - fs.Position;
ss.CopyFrom(fs, FilesByteSize) ;
finally
ss.Free;
end;
end;
finally
fs.Free;
end;
end;
**********************************
کد thread
**********************************
type
TMyThread = class(TThread)


private
FileName : TFileName; FilesByteSize : Integer
{ Private declarations }
public
constructor Create(FileName : TFileName; FilesByteSize : Integer);
procedure SplitFile ;
protected
procedure Execute; override;
published
property OnTerminate;
end;


procedure TMyThread.SplitFile ;
// FileName == file to split into several smaller files
// FilesByteSize == the size of files in bytes
var
fs, ss: TFileStream;
cnt : integer;
SplitName: String;
begin
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite) ;
try
for cnt := 1 to Trunc(fs.Size / FilesByteSize) + 1 do
begin
SplitName := ChangeFileExt(FileName, Format('%s%d', ['._',cnt])) ;
ss := TFileStream.Create(SplitName, fmCreate or fmShareExclusive) ;
try
if fs.Size - fs.Position < FilesByteSize then
FilesByteSize := fs.Size - fs.Position;
ss.CopyFrom(fs, FilesByteSize) ;
finally
ss.Free;
end;
end;
finally
fs.Free;
end;
end;


constructor TMyThread.Create(FileName : TFileName; FilesByteSize : Integer);
begin
inherited Create(True);
FileName := trdFileName ;
FilesByteSize := 512000;
end;


procedure TMyThread.Execute;
begin
inherited;
Synchronize(SplitFile);
Terminate;
end;

meysam_212
یک شنبه 11 مرداد 1394, 15:18 عصر
دستور
Synchronize(SplitFile);
رو به
SplitFile;
تغییر بده

Mahmood_M
یک شنبه 11 مرداد 1394, 20:37 عصر
دستور Synchronize وظیفه ی اجرای Procedure رو به Thread اصلی برنامه واگذار می کنه ، از Thread استفاده کردید که این اتفاق نیفته ، پس نیازی به استفاده از Synchronize نیست
زمانی از Synchronize استفاده کنید که قصد ارتباط با کامپوننتهای Visual فرم رو دارید ، مثلا نمایش پیشرفت کار در یک ProgressBar یا نمایش متن در Label یا هر چیزی که نیازمند ارتباط با کامپوننتهای Visual باشه

mahdy.asia
دوشنبه 12 مرداد 1394, 14:55 عصر
برای راهنمایی کد قبلی متشرکم، اگر خواسته باشم یک Tread رو تو تایمر بزارم چه کدی در tread و تایمر بنویسم که تا وقتی thread کارش تموم نشده timer غیر فعال بشه و therad که کارش تموم شد دوباره تایمر فعال بشه

یوسف زالی
سه شنبه 13 مرداد 1394, 00:44 صبح
به محض ورود به رویداد OnTick تایمر رو آف کنید، و بعد از اجرای دستورات در ترد، در همان رویداد execute در خط آخر، تایمر رو با روش Sync آن کنید، یا این که می تونید به فرمی که تایمر روشه پیغامی بفرستید و در اونجا برای پیغام رویداد تعریف کنید.

bobesfanji
سه شنبه 27 مرداد 1394, 09:09 صبح
برای راهنمایی کد قبلی متشرکم، اگر خواسته باشم یک Tread رو تو تایمر بزارم چه کدی در tread و تایمر بنویسم که تا وقتی thread کارش تموم نشده timer غیر فعال بشه و therad که کارش تموم شد دوباره تایمر فعال بشه

میشه بفرمایید چرا از این روش استفاده میکنید؟
بهتر نیست بجای استفاده از تایمر فکر بهتری بکنید؟

البته جواب شما رو آقای یوسف داده اند ولی بفکر روش بهتر باشید مثلا استفاده از sleep

mahdy.asia
شنبه 07 شهریور 1394, 21:42 عصر
میشه بفرمایید چرا از این روش استفاده میکنید؟
بهتر نیست بجای استفاده از تایمر فکر بهتری بکنید؟

البته جواب شما رو آقای یوسف داده اند ولی بفکر روش بهتر باشید مثلا استفاده از sleep
اگر خواسته باشم کاری رو هر 10 ثانیه یک بار انجام بدم جه روشی می تونه جایگزین مناسب تری باشه و چرا؟

Mahmood_M
یک شنبه 08 شهریور 1394, 14:43 عصر
اگر خواسته باشم کاری رو هر 10 ثانیه یک بار انجام بدم جه روشی می تونه جایگزین مناسب تری باشه و چرا؟
بستگی به کاری داره که قصد دارید انجام بدید
ممکنه استفاده از Timer گزینه مناسبی باشه ( به مراتب مناسب تر از Sleep ! )
می تونید از یک Thread استفاده کنید و در Execute مربوط به Thread زمان مورد نظر رو چک کنید ( با مقایسه تاریخ یا با استفاده از GetTickCount یا ... ) و در زمان مناسب عملیات مورد نظرتون رو انجام بدید یا اینکه از Thread ساخته شده به Thread اصلی ( Form اصلی ) پیغام بفرستید ( درواقع یک Message Handler بسازید )
یا می تونید از توابع API ویندوز مربوط به Scheduling استفاده کنید
یا بهتر اینکه از یک کامپوننت Scheduler استفاده کنید
یا ...
راه های زیادی هست که مناسب بودنشون بستگی به کار مورد نظرتون داره