PDA

View Full Version : سوال: اجرای یک Thread ،در هر ثانیه 10 بار



mojimojimoj
پنج شنبه 09 آبان 1387, 22:53 عصر
سلام

من یک ترد میخوام که تو هر ثانیه 10 بار اجرا بشه و هر بار به یک متغیر یکی اضافه کنه،
و تو textbox نشون بده ، اگه کمکم کنید خیلی ممنون میشم. اگه کدشم بنویسید که دیگه شاهکاره،

ممنون.:لبخندساده:

razavi_university
جمعه 10 آبان 1387, 00:21 صبح
شما نمیتونین به راحتی برای Tread زمان بگذارید چون فرکانس و سرعت CPU هر کامپیوتر متفاوتاست و باید براساس سیکل اون یکسری ضرب و تقسیم انجام بدین
راحترین راه استفاده از تایمر است
و مقدار Interval اون رو 100 بگذارید(چون بر حسب میلی ثانیه است) و در رویداد Tick کدی که می خوایید رو بنویسید. یادتون باشه Enable کنید

mohammad272005
جمعه 10 آبان 1387, 01:04 صبح
این سورس:


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitializeThread();
}
private Thread myThread;
private void button1_Click(object sender, EventArgs e)
{
myThread.Start();
}
private void InitializeThread()
{
var counter = 0;
Action updateUI = null;
updateUI = delegate
{
if (textBox1.InvokeRequired)
{
textBox1.Invoke(updateUI);
return;
}
textBox1.Text = (++counter).ToString();
textBox1.Update();
};
myThread = new Thread(delegate()
{
while(myThread.ThreadState == ThreadState.Running)
{
updateUI();
Thread.Sleep(100);
}
});
}
private void button2_Click(object sender, EventArgs e)
{
myThread.Abort();
}
}
اینم پروژه.
البته من راه دوست خوبم جناب razavi_university (http://barnamenevis.org/forum/member.php?u=10478) رو بیشتر از راهخودم می پسندم.

mojimojimoj
جمعه 10 آبان 1387, 12:15 عصر
با تشکر فراوان از شما دوست عزیزم چند خواهش از شما داشتم که اگر جوابم را بدهید خیلی ممنون میشم.
اول اینکه در مورد invoke توضیحی بدهید.
دوم در مورد action و آیا میشه به جاش یک متد معمولی بنویسید؟
سوم اینکه شما از delegate خیلی پیچیده استفاده کردید. میشه حذفش کنید یا تا جای ممکن سادش کنید؟
در آخر چرا InitializeThread(); را در constructor فرم قرار دادید؟
میدونم خواسته های زیادیه ولی بهش احتیاج دارم.
یه دنیا ممنون.:خجالت:

mohammad272005
جمعه 10 آبان 1387, 15:08 عصر
اول اینکه در مورد invoke توضیحی بدهید یعنی اگه thread_1 بخواد از کنترلی که تو thread_2 ایجاد شده، استفاده کنه حتما باید از thread_2 اجازه بگیره:

if (textBox1.InvokeRequired)
{
textBox1.Invoke(updateUI);
return;
}...
که اینجا updateUI اسم همون متدیه که ما الان توش هستیم. در صورتیکه InvokeRequired صحیح باشه پس هنوز thread جاری به textBox1 دسترسی نداره. در غیر اینصورت الان داره تو دل thread ایجاد کننده کنترل، اجرا میشه. نکته مهم اینجاست که اگه برنامه وارد Thread اصلی بشه دیگه توی اون کار میکنه و یه thread مستقل نیست. پس میتونه باعث freeze شدنش بشه. پس بهتره تغییر دادن UI در یه متد مستقل انجام بشه تا یه لحظه و فقط یه لحظه وارد Thread اصلی بشه و بلافاصله ازش خارج شه.
دوم در مورد action action اسم یه delegate هست که تو دل NET. تعبیه شده و استفاده از آن برای عموم آزاد است. همین. من یه annonymouse method ایجاد کردم از نوع Action و اسمشو گذاشتم updateUI حالا هرجا بخوام می تونم ازش استفاده کنم.
آیا میشه به جاش یک متد معمولی بنویسید؟ بله. فقط کافیه دستورات تو دل متد بی نام رو تو دل یه متد تعریف شده در سطح کلاس بذاری و callش کنی.
سوم اینکه شما از delegate خیلی پیچیده استفاده کردید. میشه حذفش کنید یا تا جای ممکن سادش کنید؟علتش فقط performance هست و لاغیر. بله میشه تو متد بنویسید و متد رو به thread پاس بدید.
در آخر چرا InitializeThread(); را در constructor فرم قرار دادید؟بله میشد. خیلی تو اصل قضیه فرق نداره.

razavi_university
شنبه 11 آبان 1387, 03:21 صبح
کد پیچیده ای نداره صرفا استفاده از تایمر که به صورت کامپوننت آماده وجود داره


private System.Windows.Forms.Timer timer1;
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.timer1.Interval = 100;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
timer1.Start();
private void timer1_Tick(object sender, System.EventArgs e)
{
کدی که می حخواهید در ثانیه 10 بار اجرا بشه
}

الان VS دم دستم نیست که کد رو تست کنم ولی انشالا جواب میده ;)

Amir Oveisi
شنبه 11 آبان 1387, 14:03 عصر
using this code is not good here i think.

Thread.Sleep(100);
because that locks all parts of ur program for 100 mseconds and this is not pleasure
i suggest that u use Threading.Timer class to have a good-working program

like this:

Threading.Timer timer = new Timer(new TimerCallBack(ur method),null,ur period time);

search about it
goodluck

rezaei manesh
پنج شنبه 28 مهر 1390, 12:15 عصر
سلام دوستان
من تویه یه ویندوز سرویس باید مدام پورت کام رو چک کنم و در صورت وجود اطلاعات باید بعد از گرفتن اونها و ثبت در بانک یک فیش چاپ کنم
حالا می خوام زمان سراغ گیری پورت دست خودم(در اصل کاربر)باشه یعنی بگه 10 میلی ثانیه یا چند ساعت مثلا
می خوام از روش Threading.Timer timer = new Timer(new TimerCallBack(ur method),null,ur period time)
که در بالا گفته شد برای فراخوانی تابع خودم استفاده کنم
می خوام بیشتر در موردش بودنم


Dim timer As Threading.Timer = New Timer(New TimerCallback(AddressOf ClsBase.VacateFromClock), Nothing, 1000, 100)

در ضمن موقع خواندن ا پورت کاهی مجبورم با دستور زیر سیستم رو منتظر بزارم تا اطلاعات کامل روی پورت نوشته بشه-مثلا Bewebung رو که از یک dll که همین سایت گرفتم

System.Threading.Thread.Sleep(IntReadTimeOut) '*


_bew = New Bewebung()
Dim timerDelegate As New TimerCallback(AddressOf ClsBase.VacateFromClock)
serviceTimer = New Timer(timerDelegate, Nothing, 1, 100)


این رو گذاشتم تا الان که کار می کنه اما بعضی چیز ها شو نمی فهمم

Amir Oveisi
پنج شنبه 28 مهر 1390, 12:30 عصر
منظورتون رو اینکه بیشتر در موردش میخواین بدونین درست متوجه نشدم که از چه نظر میخواین. اما این لینک رو مطالعه کنید خالی از لطف نیست
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx