PDA

View Full Version : مبتدی: اجرای یک تابع خاص هر یک ثانیه



sirvan-me
چهارشنبه 28 تیر 1391, 11:07 صبح
سلام دوستان من تو برنامم یک تابع دارم که باید هر ثانیه اجرا بشه و مقداری رو set کنه ... چطور و با چه پیاده سازی می تونم این کار رو انجام بدم .

Mahmoud.Afrad
چهارشنبه 28 تیر 1391, 11:09 صبح
timer رو جستجو بفرمایید

sirvan-me
چهارشنبه 28 تیر 1391, 11:24 صبح
منظورتون به این صورت هستش :

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();

private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 1000;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();


}

void timer1_Tick(object sender, EventArgs e)
{
//Func
}

برنامه ی من در طول روز کلا Run هستش . Timer سیستم رو زیاد درگیر نمی کنه ؟!!!!

ashe405
چهارشنبه 28 تیر 1391, 11:28 صبح
برنامه ی من در طول روز کلا Run هستش . Timer سیستم رو زیاد درگیر نمی کنه ؟!!!!

سلام دوست من بستگی داره اون تابع تایمر قراره چکار کنه
ولی فکر نکنم زیاد سیستم رو درگیر کنه فقط بستگی به تابعی که توی تایمر استفاده می کنین که قراره چقدر رم و سی پی یو از سیستمتون بگیره

sirvan-me
چهارشنبه 28 تیر 1391, 11:31 صبح
من چیزایی راجع به استفاده از Thread و Background Worker شنیدم ... با اینا و البته بدون Timer می تونم عمل بالا رو پیاده سازی کنم

samadblaj
چهارشنبه 28 تیر 1391, 11:35 صبح
آره Timer برای این کار مناسب نیست بهتر هست background worker رو مطالعه کنید.

Mahmoud.Afrad
چهارشنبه 28 تیر 1391, 11:37 صبح
میتونی یک ترد ایجاد و ران کنی و بعد توی یک حلقه برای چند ثانیه sleep کنی(واسه وقفه زمانی)

sirvan-me
چهارشنبه 28 تیر 1391, 11:37 صبح
میشه یه Reference خوب ( چه انگلیسی چه فارسی ) بهم معرفی کنید ... ترجیحا کامل و جامع باشه

sirvan-me
چهارشنبه 28 تیر 1391, 12:39 عصر
اگر بخوام از Background Worker استفاده کنم چطور می تونم یک عمل رو هر چند ثانیه تکرار کنم ؟

Mahmoud.Afrad
چهارشنبه 28 تیر 1391, 13:12 عصر
یک مثال از ترد میزارم
Thread t = new Thread(new ThreadStart(func));
bool flag = true;
private void button12_Click(object sender, EventArgs e)
{
// start thread t
t.Start();
}

private void button13_Click(object sender, EventArgs e)
{
// for kill thread t
flag = false;
}

private static void func()
{
// while flag is true
while (flag)
{
MessageBox.Show("show message by thread t");
// every 10 seconds
Thread.Sleep(10000);
}
}برای خاتمه دادن به ترد جدید flag رو false کنید(در فرم کلوزینگ منظورم هست) تا برنامه بدرستی بسته بشه.

sirvan-me
چهارشنبه 28 تیر 1391, 13:15 عصر
یک مثال از ترد میزارم
Thread t = new Thread(new ThreadStart(func));
static bool flag = true;
private void button12_Click(object sender, EventArgs e)
{
// start thread t
t.Start();
}

private void button13_Click(object sender, EventArgs e)
{
// for kill thread t
flag = false;
}

private static void func()
{
// while flag is true
while (flag)
{
MessageBox.Show("show message by thread t");
// every 10 seconds
Thread.Sleep(10000);
}
}برای خاتمه دادن به ترد جدید flag رو false کنید(در فرم کلوزینگ منظورم هست) تا برنامه بدرستی بسته بشه.

ممنون اگه دوستان لطف کنند یه مثال از Background Worker برای پیاده سازی اجرای یک تابع هر 1 ثانیه هم ارائه بدن لطف می کنن .

Saeed_m_Farid
چهارشنبه 28 تیر 1391, 13:16 عصر
میشه یه Reference خوب ( چه انگلیسی چه فارسی ) بهم معرفی کنید ... ترجیحا کامل و جامع باشه
اگه کامل و جامع میخواین همونطوری که قبلاً هم خدمت دوستان عرض کردم، فصل 26 کتاب CLR via C#‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎ (http://www.amazon.com/CLR-via-C-Third-Pro-Developer/dp/0735627045)‎‎‎ کلاً به مبحث Timerها اختصاص داره؛ یه توضیحات خلاصه هم تو تاپیک زیر دادم:
مشکل با تایمر و هنگ کردن برنامه (http://barnamenevis.org/showthread.php?347122)
و یک مقاله که تو تاپیک قبلی هم بهش رفرنس دادم: Comparing the Timer Classes in the .NET Framework Class Library (http://msdn.microsoft.com/en-us/magazine/cc164015.aspx)
____________
ولی اصلاً فکر نکنید که روالی که شما با Thread یا Background Worker برای تایمر طراحی می‌کنید احتمالاً بهتر از Timer خود دات‌نت (منظور Threading.Timer (http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx) نه اون‌یکی‌ها) خواهد بود! (بلکه به احتمال بسیار زیاد همون کارآیی رو هم نداشته باشید)
فرض کنیم، چنین کاری کردین (برای سادگی از Resume استفاده کردم):
//**************************************
public Thread thSample = new Thread(DoBackProcess);

static private void DoBackProcess()
{
while (true)
{
Thread.Sleep(500);
// DoSomething();
}
}

public bool ActTimer(bool bEnable = true)
{
if (bEnable)
switch (thSample.ThreadState)
{
case ThreadState.Stopped:
case ThreadState.Suspended:
thSample.Resume();
break;

case ThreadState.Unstarted:
thSample.Start();
break;
}
else if (!bEnable && thSample.ThreadState == ThreadState.Running)
thSample.Suspend();

return thSample.ThreadState == ThreadState.Running;
}

//**************************************

بگذریم که Resume و Suspend و ... منسوخ شدن و بنظر من! بهتره بجاش از EventWaitHandle (http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx) و متدهای WaitOne (http://msdn.microsoft.com/en-us/library/58195swd.aspx) و Set (http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.set.aspx) استفاده کنید، ولی وقتی بدونید که دستکاری و حتی مقایسه کوچک وضعیت و ... برای یک Thread (یا Mutex و ...) دیگه چقدر در طولانی مدت روی منابع سیستم تاثیر میذاره و Tread pool چه مزایایی برای فرار از این مشکل در اختیار شما قرار میده قدر Threading.Timer رو خواهید دونست! چون اون یک کلاس خاص هست که از thread pool یک thread رو invoke می‌کنه و مدیریت خیلی بهتری در تخصیص و جمع‌آوری منابع داره ...؛ زیاد کــــــــــش نمیدم تا بحث به بیراهه کشیده نشه ولی این صحبت درستی نیست:

من چیزایی راجع به استفاده از Thread و Background Worker شنیدم ... با اینا و البته بدون Timer می تونم عمل بالا رو پیاده سازی کنممثلاً در کد زیر؛ برای هر ریسورس native ای غیر از Timer بلا سرش میاد:

public static void Main()
{
System.Threading.Timer t = new System.Threading.Timer(TimerCallback, null, 0, 1000);
// Wait for the user to hit <Enter>
Console.ReadLine();
// Refer to t after ReadLine (t will survive GCs until Dispose returns)
t.Dispose();
}

private static void TimerCallback(Object o)
{
// Display the date/time when this method got called.
Console.WriteLine("In TimerCallback: " + DateTime.Now);
// Force a garbage collection to occur for this demo.
GC.Collect();
}

اگه دوست داشتین بیشتر در موردش صحبت می‌کنیم ...
+=+=+=+=+=++=
خلاصه‌اش اینکه: با خیال راحت از Threading.Timer استفاده کنید و برای کاری که میشه با اون به نتیجه رسید دنبال راه‌های فرعی نباشید..

sirvan-me
چهارشنبه 28 تیر 1391, 14:35 عصر
خیلی ممنون آقای Saeed_m_farid ، بسیار کامل و جامع توضیح دادین . تاپیک ها و Reference ی که فرمودید دارم مطالعه می کنم . فعلا چون مطلب زیادی راجع این مبحث نمی دونم درست نمیدونم وارد بحث با شما بشم که این درسته یا اون درسته ( گرچه تا حدود زیادی راضی شدم که استفاده از Timer خود زبان بهتره ) . بعد از خوندن مطالب حتما ازتون کمک می گیرم .

sirvan-me
جمعه 30 تیر 1391, 12:05 عصر
من کاری رو که می خوام انجام بدم یکبار شرح می دم ( به صورت ساده تر ) ... البته من قبلا این سوال رو مطرح کرده بودم اما با جوابا قانع نشدم ... شاید روشی که من دنبالشم خیلی ساده تر از این ها باشه .

من یه دیتابیس دارم که دو تا جدول داره :

1 ) جدول سپرده کوتاه مدت ( شماره حساب مشتری ، تاریخ افتتاح حساب ، تاریخ آخرین به روز رسانی ، تاریخ واریز مبلغ ، موجودی )
2 ) جدول سپرده بلند مدت ( شماره حساب مشتری ،تاریخ افتتاح حساب ، تاریخ واریز مبلغ ، موجودی )

برنامه ی من اینطوریه که یه مشتری میاد یه سپرده بلند مدت باز می کنه ، همزمان با اون حساب ( رکوردی تو جدول سپرده بلند مدت ) یه حساب کوتاه مدت ( رکوردی تو جدول سپرده کوتاه مدت با موجودی لولیه سود 21 درصد موجودی حساب بلند مدت ) براش باز میشه . حالا برنامه ی من باید هر بار چک کنه به محض اینکه اختلاف تاریخ و زمان بین آخرین به روز رسانی رکورد مربوط به هر مشتری تو جدول سپرده کوتاه مدت با تاریخ و زمان جاری برابر یک ماه شد ، دوباره سود 21 درصدی موجودی حساب بلند مدت رو حساب کنه و به موجودی حساب کوتاه مدت مشتری اضافه کنه ... ( این یه بخش کاره ) دوستان لطف کنن راهنمایی بفرمایید ... :ناراحت:

FastCode
جمعه 30 تیر 1391, 12:19 عصر
وااااااااااااااای
فقط وااااااااااای

سلام
این دیگه چه کاریه؟
سرم ترکید.

شما میتونید خیلی ساده موجودی حساب رو وقتی درخواست میشه حساب کنید و وقتی قرار شد که موجودی تغییر کنه(قبل از برداشت یا واریز) تغییرات رو ذخیره کنید.

pseudo code
long GetBalance(AccountInfo Acc){
long LastBalance= GetLastBalance_Internal();
DateTime LastChange = GetLastGrowthDateTime_Internal();
long CurrentBalance=(GrowthRatio ^ (DateTime.UtcNow - LastChange).Days);
return CurrentBalance;
}
برای واریز سود دو روش دارید.
مشتری مدار:
وقتی که سطری به حساب اضافه میشه, قبل از insert, این مقدار رو به حساب اضافه کنید.

سیستم بانکداری موجود در کشور:
این مقادیر رو میتونید به صورت دستی توسط کاربر هر ماه جدا insert کنید

sirvan-me
جمعه 30 تیر 1391, 13:44 عصر
وااااااااااااااای
فقط وااااااااااای

سلام
این دیگه چه کاریه؟
سرم ترکید.

شما میتونید خیلی ساده موجودی حساب رو وقتی درخواست میشه حساب کنید و وقتی قرار شد که موجودی تغییر کنه(قبل از برداشت یا واریز) تغییرات رو ذخیره کنید.

pseudo code
long GetBalance(AccountInfo Acc){
long LastBalance= GetLastBalance_Internal();
DateTime LastChange = GetLastRecordDateTime_Internal();
long CurrentBalance=(GrowthRatio ^ (DateTime.UtcNow - LastChange).Days);
return CurrentBalance;
}
برای واریز سود دو روش دارید.
مشتری مدار:
وقتی که سطری به حساب اضافه میشه, قبل از insert, این مقدار رو به حساب اضافه کنید.

سیستم بانکداری موجود در کشور:
این مقادیر رو میتونید به صورت دستی توسط کاربر هر ماه جدا insert کنید

:بوس: فوق العاده بود ... میشه راجع به کدی که نوشتین یذره توضیح بدین .. کدی که نوشتین زمانی استفاده میشه که بخوایم موجودی یه حساب و تغییر بدیم ... اگر بخوایم مشاهده هم داشته باشیم به همین صورت عمل می کنیم دیگه یعنی اطلاعات آنی حساب میشن .... بازم ممنون

sirvan-me
جمعه 30 تیر 1391, 19:54 عصر
میشه در رابطه با راهکارهای واریز سود یه توضیحی بدید .

FastCode
جمعه 30 تیر 1391, 22:31 عصر
سلام
متاسفانه این یکی دو روز درگیر ۴ ۵ تا کار شدم ولی در اولین فرصت توضیح میدم.
در ابتدا باید همه ی record ها دارای تاریخ و ساعت و ثانیه باشند که بتونید آخرین سطر رو استخراج کنید.
سود در هر لحظه برابر است با موجودی ضربدر درصد سود به توان زمان گذشته از آخرین محاسبه سود
همیشه قبل از insert باید محاسبه قبلی رو پیدا کنید و با آخرین موجودی(معمولاً سطر بعد) در فرمول بالا قرار بدید

MehdiElexal
جمعه 08 فروردین 1393, 16:14 عصر
یک مثال از ترد میزارم
Thread t = new Thread(new ThreadStart(func));
static bool flag = true;
private void button12_Click(object sender, EventArgs e)
{
// start thread t
t.Start();
}

private void button13_Click(object sender, EventArgs e)
{
// for kill thread t
flag = false;
}

private static void func()
{
// while flag is true
while (flag)
{
MessageBox.Show("show message by thread t");
// every 10 seconds
Thread.Sleep(10000);
}
}برای خاتمه دادن به ترد جدید flag رو false کنید(در فرم کلوزینگ منظورم هست) تا برنامه بدرستی بسته بشه.

رویداد button13 ترد را متوقف نمیکنه
چطور باید ترد را در حین انجام کار متوقف کرد ؟
نه که فرم بسته شه ترد وایسه نه
موقع اجرای برنامه رو همون دکمه 13 که زد هر جا هست متوقف شه
چطور میشه ؟ ممنون