PDA

View Full Version : مجموعه ای از تایمرها در یک فرم.



pouria_bayat
چهارشنبه 23 مرداد 1392, 20:05 عصر
سلام دوستان من یکسری تایمر به صورت ارایه تعریف کردم که به صورت دینامیکی انها رو new و اجرا میکنم مشگل من زمانی هستش که همه تایمرها نمی تونن از یک تابع برای شمارش استفاده کنند:
private void Timer_Tick(object sender, EventArgs e)
{
if (Secound[indexPush] < 59)
{
Secound[indexPush]++;
}
else if (Secound[indexPush] == 59 && Min[indexPush] < 59)
{
Secound[indexPush] = 0;
Min[indexPush]++;
}
else if (Secound[indexPush] == 59 && Min[indexPush] == 59)
{
Secound[indexPush] = 0;
Min[indexPush] = 0;
Houre[indexPush]++;
}
lblTime[indexPush].Text = (Secound[indexPush] + " : " + Min[indexPush] + " : " + Houre[indexPush]).ToString();
}
فرض کنیم توی فرم برنامه 10 تا دکمه داریم و 10 تا label که با فشار دادن هر دکمه label مربوط به اون دکمه شروع میکنه به صورت تایمر شمارشی اجرا بشه همانطور که توی تکه کد مشخص هستش ولی متاسفانه برای هر تایمر باید یک تابع Timer_Tick تعریف کنم. میشه راهنمایی کنید ممنون میشم.

pouria_bayat
چهارشنبه 23 مرداد 1392, 20:08 عصر
برنامه مثل یک برنامه ورزشی هستش که هر چند دقیقه یک نفر شروع به دویدن میکنه و با فشار دادن یکی از دکمه ها یک تایمر شروع به کار میکنه و زمان اون رو به صورت یک تایمر شمارشی توی یک label نشان میده و تعداد دونده ها میتونه 10 یا 1 عدد باشه...

pouria_bayat
پنج شنبه 24 مرداد 1392, 09:08 صبح
یعنی واقعا کسی نمیتونه یک کمک ساده در این زمینه به ما بکنه؟
برای توضیح ساده تر تایمرهای کافی نت همچین چیزی دارند اگر دقت کرده باشید.

hamid_hr
پنج شنبه 24 مرداد 1392, 09:25 صبح
من باشم يه تابع مينويسم به اين صورت

while(true){
thread.sleep(1000);
//كدها
}



اونو هر بار كه خواستم با ترد اجرا ميكنم

danialafshari
پنج شنبه 24 مرداد 1392, 09:54 صبح
سلام
برای اینکار بهتره از thread استفاده کنید
البته بهتره قبلش درباره برنامتون شرح بدید در ابتدای برنامه نویسیم برنامه ای نوشتم با 8 تایمر که بعدا همون رو کردم 1 تایمر و باقی اضاف بود !
الانم اگه ویرایشش کنم می کنمش با thread
موفق باشی

pouria_bayat
پنج شنبه 24 مرداد 1392, 10:13 صبح
سلام ممنون از همگی توضیح در مورد برنامه:

private static int[] Houre = new int[10];
private static int[] Min = new int[10];
private static int[] Secound = new int[10];
Label[] lblTime = new Label[10];
static Button[] cb = new Button[10];

همانطور که می بینید در اعلان متغیرها و Obj ها من برای فرم برنامه 10تا دکمه به صورت ارایه در نظر گرفتم که دکمه ها رو به صورت Dynamically تعریف میکنم و بالای هر دکمه 10 تا label قرار دادم تا با فشار دادن هر دکمه(رویداد کلیک) label مربوط به هر دکمه شروع به شمارش کنه فرض کنیم اگر دکمه شماره یک را فشار دادیم Label شماره یک به صورت تایمر(00:00:00) شروع به شمارش میکنه تا زمانی که همون دکمه فشار داده بشه و همان Label زمان رو متوقف کنه. حالا تشخیص دادن این که کدوم دکمه فشار داده شده یا کدوم Label باید شمارش بشه کار سختی نیست ولی وقتی میخواهم از تردها داخل رویداد کلیک هر دکمه استفاده کنم برای اینکه کد نویسی کمتر بشه یک تابع تعریف کردم که اون تردها اون تابع رو اجرا کنند تابع مربوطه:

rivate void Timer_Tick()
{
if (Secound[indexPush] < 59)
{
Secound[indexPush]++;
}
else if (Secound[indexPush] == 59 && Min[indexPush] < 59)
{
Secound[indexPush] = 0;
Min[indexPush]++;
}
else if (Secound[indexPush] == 59 && Min[indexPush] == 59)
{
Secound[indexPush] = 0;
Min[indexPush] = 0;
Houre[indexPush]++;
}
lblTime[indexPush].Text = (Secound[indexPush] + " : " + Min[indexPush] + " : " + Houre[indexPush]).ToString();
}

ولی مشگل اینه که اگر فرضا دکمه یک رو فشار بدم Label دکمه یک به درستی شمارش میکنه ولی اگر دکمه دوم رو کلیک کنم Label دکمه دوم از ادامه شمارش دکمه یک کارشو ادامه میده وlabel دکمه یک شمارشش رو قطع میکنه....
در حقیقت من میخواهم هر دفعه از تابع مربوطه یک Obj جدید بسازه تا با هم زمانها قاطی نشن یا فشار دادن دکمه بعدی و شروع تایمر جدید باعث قطع شدن تایمر قبلی نشه چه تغییری باید توی تابع مربوطه بدم؟
در ضمن با تشکر از همگی من کار با تردها رو به خوبی بلدم.

pouria_bayat
پنج شنبه 24 مرداد 1392, 10:23 صبح
در حقیقت اینو بگم هر موقع دکمه دوم فشار داده بشه label دوم شروع به شمارش میکنه ولی با سرعت 5000 میلی ثاینه یعنی هر نیم ثانیه یکبار دلیلشم اینه که یکبار این تابع قبلا توسط یک ترد دیگه توسط رویداد کلیک دکمه یک صدا زده شده.و البته Label یک هم شمارش خود رو قطع میکنه من حدس میزنم مشگل کار از اینجاست:

lblTime[indexPush].Text = (Secound[indexPush] + " : " + Min[indexPush] + " : " + Houre[indexPush]).ToString();
توضیح دیگه اینکه اگر برای هر ترد یک تابع جداگانه تعریف کنم مشگل برطرف میشه...
فکر کنم توضیحات کامل بود و مشگل من کاملا مشخصه.

hamid_hr
پنج شنبه 24 مرداد 1392, 10:49 صبح
private void ThreadTimer(object Lb)
{
while(true)
{
if (Secound[indexPush] < 59)

{

Secound[indexPush]++;

}

else if (Secound[indexPush] == 59 && Min[indexPush] < 59)

{

Secound[indexPush] = 0;

Min[indexPush]++;

}
else if (Secound[indexPush] == 59 && Min[indexPush] == 59)
{
Secound[indexPush] = 0;
Min[indexPush] = 0;
Houre[indexPush]++;
}
((control)lb).text = (Secound[indexPush] + " : " + Min[indexPush] + " : " + Houre[indexPush]).ToString();
thread.sleep(1000);
}
}


اينو با ترد اجراكني اصلا قاطي نميكنه
هر بار كه اجرا كني يه نمونه جديدشو اجرا ميكنه
قفط بايد اون ليبلي كه ميخواي داخلش نوشته بشه رو بهش پاس بدي

pouria_bayat
پنج شنبه 24 مرداد 1392, 11:09 صبح
سلام ممنون دوست عزیز ولی حمید جان فکر کنم نمیشه به متد یک ترد آرگومانی ارسال کرد و نباید پارامتری بگیره درسته یا من اشتباه میکنم؟

Label ne = new Label();
RunTime[indexPush] = new ThreadStart(ThreadTimer(ne));
ارور میگیره...

hamid_hr
پنج شنبه 24 مرداد 1392, 11:12 صبح
ميشه
به ترد يه شي از نوع object ميشه ارسال كرد

thread t1=new thread(threadtimer);
t1.start(lable1);

pouria_bayat
پنج شنبه 24 مرداد 1392, 11:31 صبح
ممنون حمید جان بابت راهنمایت با کمی تغییرات درست شد:
ولی هنوز یک مشگل هستش اینکه وقتی دکمه دوم رو کلیک میکنیم تایمرش دوتا دوتا اضافه میکنه یعنی 2 بعدش 4 و الی آخر(0:0:2بعدش 0:0:4) .تایمر یک هم همینوطر میشه البته تا زمانی که فقط یکیشون کار میکنه درست هستش ولی از وقتی که تایمر 2 شروع میشه این خطا رخ میده...

static void ThreadTimer(object Lb)
{
while (true)
{
var TimeSet = new Action(() =>
{
if (Secound[indexPush] < 59)
{

Secound[indexPush]++;

}

else if (Secound[indexPush] == 59 && Min[indexPush] < 59)
{

Secound[indexPush] = 0;

Min[indexPush]++;

}
else if (Secound[indexPush] == 59 && Min[indexPush] == 59)
{
Secound[indexPush] = 0;
Min[indexPush] = 0;
Houre[indexPush]++;
}
((Control)Lb).Text = (Secound[indexPush] + " : " + Min[indexPush] + " : " + Houre[indexPush]).ToString();
});
if (((Control)Lb).InvokeRequired)
{
((Control)Lb).BeginInvoke(TimeSet);
}
else
TimeSet();
Thread.Sleep(1000);
}
}

pouria_bayat
پنج شنبه 24 مرداد 1392, 11:38 صبح
اگر بتونیم indexPush رو براش بفرستیم فکر کنم درست بشه...
راهی هست که بشه اینکارو براش انجام بدیم؟

hamid_hr
پنج شنبه 24 مرداد 1392, 11:41 صبح
مال ايندكس اون ارايه هات هستش
اونا رو بيا داخل تابع به صورت محلي تعريف كن درست ميشه

pouria_bayat
پنج شنبه 24 مرداد 1392, 11:45 صبح
مال ايندكس اون ارايه هات هستش
اونا رو بيا داخل تابع به صورت محلي تعريف كن درست ميشه
خیلی خیلی لطف کردی درست شد.
ممنون بابت زحمتهایی که کشیدی و وقتی که گذاشتی.

مهرداد صفا
پنج شنبه 24 مرداد 1392, 12:38 عصر
با سلام.
کد زیر را امتحان کنید:


//in the name of god
//صل الله علی محمد و آله

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Dictionary<Timer, UInt64> timers = new Dictionary<Timer, ulong>();
Dictionary<Timer, Label> labels = new Dictionary<Timer, Label>();
Dictionary<Button, Timer> buttons = new Dictionary<Button, Timer>();
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
this.Size = Screen.PrimaryScreen.Bounds.Size;
for (int i = 0; i < 10; i++)
{
timers.Add(new Timer() { Interval = 1000, Enabled = false }, 0);
labels.Add(timers.Last().Key, new Label() { Top = 60, Left = this.Width / 11*i,BackColor=Color.Yellow });
buttons.Add(new Button() { Text = "button" + i.ToString(), Top = 120, Left = labels.Last().Value.Left,BackColor=labels.Last().V alue.BackColor }, timers.Last().Key);
timers.Last().Key.Tick += (s, args) =>
{
Timer t = (s as Timer);
timers[t]++;
TimeSpan temp = TimeSpan.FromSeconds(timers[t]);
labels[t].Text = temp.Hours.ToString() + ":" + temp.Minutes.ToString() + ":" + temp.Seconds.ToString();
};
buttons.Last().Key.Click += (s, args) => buttons[(Button)s].Enabled = !buttons[(Button)s].Enabled;

this.SuspendLayout();
this.Controls.Add(labels.Last().Value);
this.Controls.Add(buttons.Last().Key);
this.ResumeLayout();
this.BackColor = Color.Black;

}
}
}
}


اگر دقت کنید Timer ها و Label ها و button ها به صورت Dictionary تعریف شدند، به این دلیل که بتوان مثلا در رویداد یک Timer به Label متناظر با آن دسترسی داشت و همینطور در مورد Button ها.
در مورد زمان هم در هر ثانیه یک واحد به مقداری که برای هر Timer در نظر گرفته شده اضافه می شود. در آخر هم مقدار هر Timer به TimeSpan تبدیل شده در Label متناظر قرار می گیرد.

zahra63h
چهارشنبه 22 مرداد 1393, 08:19 صبح
سلام
این اولین پست من در برنامه نویس و نمید.نستم چطوری یک تاپیک جدید ایجاد کنم، برا همین در ادامه این تاپیک، پست زدم.
در ضمن تو برنامه نویسی تقریبا تازه کارم.
میخوام توی صفحه ای در یک بازه زمانی معین، دکمه هایی قرار دهم که متن آن زمان با فاصله ای معین باشه.
مثلا از ساعت 10 تا 12، را 10 دقیقه 10دقیقه نشون بدم. یعنی 10، 10:10 ، 10:20، 10:30 و .....