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

نام تاپیک: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

  1. #1
    کاربر تازه وارد
    تاریخ عضویت
    خرداد 1389
    محل زندگی
    مشهد
    پست
    46

    Lightbulb راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    سلام عزیزان
    شاید سوالی که میپرسم خیلی مبتدی باشه.

    من دارم یک برنامه مینویسم که به دلایلی باید هر 5 ثانیه وصل بشه به سایت من و یک نوشته رو از روی سایت بخونه، بعد در ازای فرمانی که از سرور گرفته کاری رو انجام بده.

    من یک تایمر ایجاد کردم که هر 5 ثانیه کد زیر رو اجرا میکنه:


    function Get(): string;
    var
    Params: TStringList;
    IHTTP: TIDHTTP;
    begin
    IHTTP := TIDHTTP.Create(nil);
    Params := TStringList.Create;
    Params.Add('request=somthing' );
    try
    Result := IHTTP.Post('http://domain.com/get.php',Params);
    finally
    FreeAndNil(IHTTP);
    FreeAndNil(Params);
    end;
    end;


    نوشته ای که از طریق سایت دریافت میشه خیلی کوتاه و کم حجم هست اما متاسفانه هنگامی که نرم افزار میخواد همین حجم کم رو دریافت کنه، یه کوچولو درگیر میشه و برای یه لحظه گیر میکنه


    سوال من اینجاست


    چطور میتونم این کد رو طوری اجرا کنم که جدا از برنامه من باشه. یعنی یه جوری که وقتی میخواد وصل بشه به سرور ، اگر برای چند لحظه گیر هم کرد، برنامه اصلی گیر نکنه.


    لطفا راهماییم کنید! خیلی مهمه.

    ضمنا! لطفا کامل توضیح بدید چون من هنوز مبتدی هستم.

    ممنون

  2. #2

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    باید قسمت دانلود رو تو یک Thread جدا پیاده کنید ، بارها در مورد Thread بحث شده ، همین عبارت رو جست و جو کنید .

  3. #3
    کاربر تازه وارد
    تاریخ عضویت
    خرداد 1389
    محل زندگی
    مشهد
    پست
    46

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    نقل قول نوشته شده توسط مجتبی تاجیک مشاهده تاپیک
    باید قسمت دانلود رو تو یک Thread جدا پیاده کنید ، بارها در مورد Thread بحث شده ، همین عبارت رو جست و جو کنید .
    ممنون
    ولی با thread هم نشد. بازم گیر میکنه. قطعا یه جایی اشتباه کردم

    این کد منه

    یک یونیت دارم که thread داخلش قرار داره:




    type
    TGetText = class(TThread)
    public
    function Get():string;
    private
    address: string;

    protected
    procedure Execute; override;

    end;

    implementation
    uses main;


    function TGetText.Get(): string;
    var
    Params: TStringList;
    IHTTP: TIDHTTP;
    begin
    IHTTP := TIDHTTP.Create(nil);
    Params := TStringList.Create;
    Params.Add('request=somthing' );
    try
    Result := IHTTP.Post('http://domain.com/get.php',Params);
    finally
    FreeAndNil(IHTTP);
    FreeAndNil(Params);
    end;
    end;


    procedure TGetText.Execute;
    begin
    //Synchronize(Get);
    if Terminated then
    Exit;
    end;





    حالا داخل پروسیجر تایمر، این کد رو نوشتم:





    procedure Tmainform.input_checkTimer(Sender: TObject);
    var
    Text_string, Web_String, Temp_WEb_String: string;
    temp: string;
    i: integer;
    GetITEGText : TGetText;
    begin
    GetITEGText:= TGetText.Create(True);
    GetITEGText.FreeOnTerminate := True;
    GetITEGText.Resume;
    Web_String := GetITEGText.Get();
    // do somthing
    if GetITEGText.ExternalThread = false then
    GetITEGText.Terminate;





    کدهای بالا رو از روی یک مثال نوشتم. حالا نمیدونم کجاش اشتباه کردم.

  4. #4

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    استفاده از Synchronize باعث میشه تا تابع فراخوان شده در Context ترد اصلی برنامه ( Main Thread ) اجرا بشه و زمانی کاربرد داره که شما بخواین از داخل تردتون به اشیاء فرم دسترسی داشته باشید ( مثلا روند یک ProgressBar رو تغییر بدید یا ... ) که در این صورت برای همزمان سازی تردتون با Main Thread میتونید از Synchronize استفاده کنید ، پس ادامه اون روند فریز شدن طبیعی هست ، در ضمن روند اجرای ترد رو باید به روال Execute ترد بسپارید نه اینکه مستقیما تابع Get رو صدا بزنید ، اینطوری عملا هیچ استفاده ای از Thread نکردی !

    کلا تردتون پر از اشکال هست ، تا بعد از ظهر سرم شلوغه و نمیتونم کمکت کنم ، اگر تا اون موقع به جایی نرسیدی کد رو برات اصلاح میکنم .

  5. #5

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    برای استفاده از Thread باید درخواستهایی که از ترد و Object های متعلق به اون دارید رو درون Execute مربوط به Thread اجرا کنید ، وقتی درون تردتون چیزی رو Create میکنید ، اون شیء متعلق به ترد هست ، چیزی که باعث به اصطلاح هنگ کردن برنامه میشه درخواست استفاده از آبجکتهای یک ترد از طرف ترد دیگه بدون همزمان سازیه ، در نمونه ی بالا می تونید مقدار String خروجی رو در یک متغیر در داخل خود ترد قرار بدید و از اون بخونید :
    type
    TGetText = class(TThread)
    public
    Rst : String;
    procedure Get;
    private
    Params : TStringList;
    IHTTP : TIDHTTP;
    Address: string;
    protected
    procedure Execute; override;

    end;

    بهتره که آبجکت ها درون بدنه ترد تعریف بشند تا درون Procedure

    procedure TGetText.Get;
    begin
    IHTTP := TIDHTTP.Create();
    Params := TStringList.Create;
    Params.Add('request = somthing');
    try
    Rst := IHTTP.Post(Address, Params);
    finally
    FreeAndNil(IHTTP);
    FreeAndNil(Params);
    end;
    end;


    procedure TGetText.Execute;
    begin
    try
    Get;
    finally
    Terminate;
    end;
    end;


    البته بهتره که Object ها در رویداد OnCreate ترد Create و در رویداد OnDestroyed ترد هم Free بشن

    var
    Text_string, Web_String, Temp_WEb_String: string;
    temp: string;
    i: integer;
    GetITEGText : TGetText;
    begin
    GetITEGText := TGetText.Create(True);
    GetITEGText.FreeOnTerminate := True;
    GetITEGText.Resume;
    if GetITEGText.Rst <> '' then
    Web_String := GetITEGText.Rst;
    end;


    این تغییرات مشکل هنگ کردن برنامه رو حل میکنن ولی اگر قصد استفاده بهتر از ترد رو دارید بهتره کمی در موردش تحقیق کنید ، در همین سایت هم قبلا بحث های مفیدی شده ، موفق باشید ...

  6. #6
    کاربر تازه وارد
    تاریخ عضویت
    خرداد 1389
    محل زندگی
    مشهد
    پست
    46

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    ممنون

    اما یه جای کار میلنگه!!!

    وقتی کد زیر اجرا میشه:


    var
    Text_string, Web_String, Temp_WEb_String: string;
    temp: string;
    i: integer;
    GetITEGText : TGetText;
    begin
    GetITEGText := TGetText.Create(True);
    GetITEGText.FreeOnTerminate := True;
    GetITEGText.Resume;
    if GetITEGText.Rst <> '' then
    Web_String := GetITEGText.Rst;
    end;



    وقتی از طریق main مقدار rst رو دریافت میکنم خالی هستش، در حالی که وقتی در داخل ترد تست میکنم، rst مقدار داره! یعنی GetITEGText.Rst یک مقدار خالی رو بهم میده.
    مگه ممکنه؟


    ممنون میشم راهنمایی کنید.

  7. #7

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    نقل قول نوشته شده توسط ahmad.khaliq مشاهده تاپیک
    ممنون

    اما یه جای کار میلنگه!!!

    وقتی کد زیر اجرا میشه:


    var
    Text_string, Web_String, Temp_WEb_String: string;
    temp: string;
    i: integer;
    GetITEGText : TGetText;
    begin
    GetITEGText := TGetText.Create(True);
    GetITEGText.FreeOnTerminate := True;
    GetITEGText.Resume;
    if GetITEGText.Rst <> '' then
    Web_String := GetITEGText.Rst;
    end;



    وقتی از طریق main مقدار rst رو دریافت میکنم خالی هستش، در حالی که وقتی در داخل ترد تست میکنم، rst مقدار داره! یعنی GetITEGText.Rst یک مقدار خالی رو بهم میده.
    مگه ممکنه؟


    ممنون میشم راهنمایی کنید.
    اون کد مشکل داره ، متغییر Rst رو به صورت سراسری تعریف کنید .

  8. #8

    نقل قول: راهنمایی کنید: جلوگیری از گیر کردن برنامه، هنگام دانلود یک فایل

    بهتره که آبجکت ها درون بدنه ترد تعریف بشند تا درون Procedure
    مزیت خاصی نداره، بخصوص تنها استفاده کننده اون اشیاء همون متد Get هست، نه مابقی متدهای اون کلاس. در ضمن، Thread ایی که اجرای متد Execute اش به اتمام برسه، به طور خودکار Terminate میشه، نیازی به فراخوانی Terminate در انتهای متد Execute نیست.


    وقتی از طریق main مقدار rst رو دریافت میکنم خالی هستش، در حالی که وقتی در داخل ترد تست میکنم، rst مقدار داره! یعنی GetITEGText.Rst یک مقدار خالی رو بهم میده.
    من قبلا هم گفتم، قبل از استفاده از Thread ها باید خوب درباره شان و مفهوم شان مطالعه کنید، وگرنه استفاده از Thread بیشتر باعث ایجاد مشکل میشه تا رفع مشکل. اگر کل مشکل شما اینه که برنامه برای چند لحظه در هنگام دریافت متن از اینترنت حالت قفل شده پیدا میکنه، بهتره به جای استفاده از Thread، یک کامپوننت IdAntiFreeze روی فرم تان بیاندازید، تا دیگه برنامه تان هنگام کار با کامپوننت های Indy حالت قفل شده پیدا نکنه.

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

    برای کار شما، ساده ترین حالت استفاده از Thread این هست که از همون متد Get خودتون در داخل متد Execute استفاده کنید، فقط یک خصوصیت برای نگهداری مقدار خروجی Thread به صورت read-only در داخل کلاس Thread تعریف کنید، و خروجی Get را داخل آن بریزید. برای دریافت این مقدار از Thread، می تونید از رویداد OnTerminate اون Thread استفاده کنید. وقتی Thread اجراش به پایان رسید، اون رویداد فراخوانی میشه، و شما می تونید مقدار خصوصیت مربوطه را در Thread اصلی دریافت کنید. کدتون میشه یک چیزی شبیه به این:

    TGetText = class(TThread)
    private
    FResult: string;
    protected
    procedure Execute; override;
    function Get: string;
    public
    property Result : string read FResult;
    end;


    procedure TGetText.Execute;
    begin
    FreeOnTerminate := True;
    FResult := Get;
    end;

    function TGetText.Get: string;
    begin
    /// Your get() method code
    end;


    کد Thread اصلی:

    TForm1 = class(TForm)
    procedure Timer1OnTimer(Sender: TObject);
    private
    FGetText : TGetText;
    procedure GetTextTerminate(Sender: TObject);
    public
    end;


    procedure TForm1.Timer1OnTimer(Sender: TObject);
    begin
    if Assigned(FGetText) then
    begin
    FGetText.Terminate;
    FGetText.WaitFor;
    FreeAndNil(FGetText);
    end;

    FGetText := TGetText.Create(True);
    FGetText.OnTerminate := GetTextTerminate;
    FGetText.Resume;
    end;

    procedure TForm1.GetTextTerminate(Sender: TObject);
    begin
    ShowMessage(FGetText.Result);
    FGetText := nil;
    end;


    لطفا همینطوری Copy\Paste اش نکنید، درباره اش مطالعه کنید.

    موفق باشید


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

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

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

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