PDA

View Full Version : قرار دادن تابعی که ورودی دارد در یک Thread



saman_h
جمعه 06 مرداد 1391, 20:07 عصر
سلام دوستان
من یا تابع نوشتم که ورودی داره به این صورت :
public void showProgressBar(ToolStripProgressBar prg_resive)
{
int i = 0;
prg_resive.Minimum = 0;
prg_resive.Maximum = size;
prg_resive.Value = 0;
prg_resive.Visible = true;
while (size > i)
{
i++;
prg_resive.Value += 1;
// Thread.Sleep(10);
}
prg_resive.Visible = false;
}
حالا وقتی میخوام یه جایی از بنامم این تابع رو با یه Thread صدا بزنم و اجرا کنم ارور میده . به این صورت :
Thread _t1 = new Thread(new ThreadStart(showProgressBar(p1)));
_t1.Start();


ممنون میشم راهنماییم کنید که باید چیکار کنم . درضمن حتما باید از thread استفاده کنم نه از timer نه چیز دیگه ای
با تشکر

saman_h
جمعه 06 مرداد 1391, 21:08 عصر
میدونم اگع تابع من ورودی نداشت راحت اینطوری میشد :
Thread _t1 = new Thread(new ThreadStart(showProgressBar()));
_t1.Start();
اما الان که ورودی داره ارور میده . ممنون میشم راهنماییم کنید

the king
جمعه 06 مرداد 1391, 21:24 عصر
میدونم اگع تابع من ورودی نداشت راحت اینطوری میشد :
Thread _t1 = new Thread(new ThreadStart(showProgressBar()));
_t1.Start();
اما الان که ورودی داره ارور میده . ممنون میشم راهنماییم کنید


Thread _t1 = new Thread(showProgressBar);
_t1.Start(p1);



public void showProgressBar(object value)
{
ToolStripProgressBar prg_resive = (ToolStripProgressBar)value;
int i = 0;
prg_resive.Minimum = 0;
prg_resive.Maximum = size;
prg_resive.Value = 0;
prg_resive.Visible = true;
while (size > i)
{
i++;
prg_resive.Value += 1;
// Thread.Sleep(10);
}
prg_resive.Visible = false;
}


فقط حواس تون باشه که اگه اون p1 روی فرم ئه، برنامه تون خطا میده چون Thread ئه اجازه دسترسی به p1 روی فرم رو نداره.
رجوع شود به :
سوال: مشکل در Invoke (http://barnamenevis.org/showthread.php?352854)

saman_h
یک شنبه 08 مرداد 1391, 20:35 عصر
سلام
خب آره اون ProgressBar روی فرمم هست ( همون p1 منظورم هستا ) .
اون مفهوم Invoke رو درست متوجه نشدم ! الان من اگه بخوام اون P1 که یه شی ProgressBar هست رو به عنوان ورودی تابعم بذارم و اون تابع رو با Thread اجرا کنم باید چیکار کنم ؟! چطوری باید کدش رو بنویسم ؟ اون چیزی که توی اون لینک هس مربوط به Text هست حالا من میخوام به یک شی دسترسی داشته باشم . یکم گیج شدم !!!
ممنون میشم کمکم کنید ...

مرتضی تقدمی
یک شنبه 08 مرداد 1391, 21:28 عصر
سلام
می تونی یک تابع که ورودی نداره رو تعریف کنی و بعد داخلش, تابع دارای چند ورودی رو صدا بزنی.
موفق باشید

the king
یک شنبه 08 مرداد 1391, 22:12 عصر
سلام
خب آره اون ProgressBar روی فرمم هست ( همون p1 منظورم هستا ) .
اون مفهوم Invoke رو درست متوجه نشدم ! الان من اگه بخوام اون P1 که یه شی ProgressBar هست رو به عنوان ورودی تابعم بذارم و اون تابع رو با Thread اجرا کنم باید چیکار کنم ؟! چطوری باید کدش رو بنویسم ؟ اون چیزی که توی اون لینک هس مربوط به Text هست حالا من میخوام به یک شی دسترسی داشته باشم . یکم گیج شدم !!!
ممنون میشم کمکم کنید ...
بعضی وقتی لازمه خودتون Thread بسازید چون کاری که انجام می دهید پیچیده و غیر عادیه اما در مورد کدی که شما می نویسید روال ساده است.
این Thread ای که شما ساخته اید پیچیدگی نداره، یک کار روتین و ساده انجام میده، به همین جهت از BackgroundWorker استفاده کنید خیلی بهتره.
خودش Thread می سازه و کدی که می خواهید رو هم در اون Thread اجرا می کنه، بجز بخشی که مربوط به ProgressBar و فرم ئه.

مثال هر دو شیوه رو پیوست کردم :
90454

saman_h
سه شنبه 10 مرداد 1391, 00:36 صبح
بعضی وقتی لازمه خودتون Thread بسازید چون کاری که انجام می دهید پیچیده و غیر عادیه اما در مورد کدی که شما می نویسید روال ساده است.
این Thread ای که شما ساخته اید پیچیدگی نداره، یک کار روتین و ساده انجام میده، به همین جهت از BackgroundWorker استفاده کنید خیلی بهتره.
خودش Thread می سازه و کدی که می خواهید رو هم در اون Thread اجرا می کنه، بجز بخشی که مربوط به ProgressBar و فرم ئه.

مثال هر دو شیوه رو پیوست کردم :
90454


مرسی عالی بود فقط اگه یکم توضیحات میذاشتید که داره چه اتفاقی میفته عالی میشد ... اگه واسه این کار هم وقت بذارید ممنونتون میشم چون دوس ندارم برم کپیش کنم . اصولشو یاد بگیرم بهتره

the king
سه شنبه 10 مرداد 1391, 00:40 صبح
مرسی عالی بود فقط اگه یکم توضیحات میذاشتید که داره چه اتفاقی میفته عالی میشد ... اگه واسه این کار هم وقت بذارید ممنونتون میشم چون دوس ندارم برم کپیش کنم . اصولشو یاد بگیرم بهتره

رجوع شود به :
BackGround Worker (http://barnamenevis.org/showthread.php?353379-BackGround-Worker)

saman_h
سه شنبه 10 مرداد 1391, 14:23 عصر
ممنون میشم واسه اون یکی مثال هم توضیحات بذارید . درصورت امکان همینجا کدهارو بذارید یه توضیح روش بدید
مرسی

the king
سه شنبه 10 مرداد 1391, 16:34 عصر
ممنون میشم واسه اون یکی مثال هم توضیحات بذارید . درصورت امکان همینجا کدهارو بذارید یه توضیح روش بدید
مرسی

SetProgressBar تعریف یک delegate ئه، delegate ای که دو پارامتر داره, پارامتر اول ProgressBar ای که باید مقداری برای Value اش تعیین بشه و پارامتر دوم مقدار مورد نظر.

private delegate void SetProgressBar(ToolStripProgressBar prg_resive, int progress);


متد SetProgress مطابق همین delegate طراحی شده، مقدار Value یک ProgressBar رو تغییر میده. اگر مقدار 0 باشه آشکار اش می کنه
و مقدار حداکثر اش رو هم تنظیم می کنه. اگر هم مقدار size باشه، پنهان اش می کنه.

private void SetProgress(ToolStripProgressBar prg_resive, int progress)
{
if (progress == 0)
{
prg_resive.Minimum = 0;
prg_resive.Maximum = size;
prg_resive.Visible = true;
}
else if (progress == size)
{
prg_resive.Visible = false;
}
prg_resive.Value = progress;
}


پارامتر ورودی متد ای که Thread اجرا می کنه از نوع object است و داخلش یک ToolStripProgressBar هست. این ToolStripProgressBar را
داخل متغیر prg_resive از نوع object تبدیل می کنیم به ToolStripProgressBar

public void showProgressBar(object value)
{
ToolStripProgressBar prg_resive = (ToolStripProgressBar)value;


این فراخوانی متد SetProgress است که مقدار Value ئه prg_resive رو 0 کنه. چون Invoke شده، Thread اصلی
که مدیریت فرم رو انجام اجرایش می کنه، نه این Thread جدیدی که الان داره اجرا میشه :

Invoke(new SetProgressBar(SetProgress), prg_resive, 0);


اینم شبیه بالایی است، فرق اش اینه که با مقدار i فراخوانی میشه :

Invoke(new SetProgressBar(SetProgress), prg_resive, i);