الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

محاكاة الدالة setTimeout الخاصة بالـ JavaScript

بدأه محمد رضى في 14 أبريل 2011 · 7 رد · 1,739 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله تعالى و بركاته...

قد نحتاج في بعض مشاريعنا البرمجية تنفيد كود بعد انقضاء وقت محدد. هذا الكود لا يحتاج إلى إعادة التنفيذ مرات عديدة فنضعه داخل Timer. من هذا المنطلق يمكننا كتابة دالة بسيطة تحاكي الدالة setTimeout للـ JavaScript. هذه الدالة تستقبل معاملين الأول هو الدالة المراد المناداة عليها وقت انتهاء الوقت المحدد على المعامل الثاني.

الدالة التي سنرى بعد قليل ستعمل بنفس المبدأ أي أنها سترجع بدون انتظار و بعض انقضاء الوقت المحدد سيتم تنفيذ الكود المحدد لها.

// الفئة التي تحتوي الدالة 
public class Timeout
{
// تحديد تعريف الدوال التي يمكن المناداة عليها
	public delegate void TimeoutMethod();
	// تمكن الدالة من المناداة على الدالة المحددة بـ method بعد انقضاء الوقت millis
	public static void SetTimeout(int millis, TimeoutMethod method)
	{
// انشاء مسلك خاص لتنفيد العملية
		System.Threading.Thread thrd;
		thrd = new System.Threading.Thread(delegate() {
// انتظار انتهاء الوقت المخصص
	System.Threading.Thread.Sleep(millis);
// المناداة على الدالة المحددة
	method();
            });
// لتفادي تجميد التطبيق وقت غلقه من طرف المستخدم
		thrd.IsBackground = true;
// تنفيد الكود في مسلك خاص
		thrd.Start();
	}
}

استخدام الدالة SetTimeout الخاصة بنا سهل جدا :

انتظار ثانية ثم تنفيد كود :

Timeout.SetTimeout(1000, delegate() {
	Console.WriteLine("Tick");
});

انتظار ثانية ثم المناداة على دالة مستقلة MyMethod حيث يكون تعريف الدالة من دون معاملات void MyMethod() { ... } :

Timeout.SetTimeout(1000, MyMethod);

ملاحظة :

يجب الانتباه إلى أن كود الدالة Timeout.SetTimeout يتم تنفيذه في مسلك خاص و محاولة الوصول إلى مربعات تحكم عبر الكود المحدد للدالة سيرفع استثناء من نوع InvalidOperationException لأن إطار الدوت نت يمنع الوصول إلى مربعات التحكم من مسلك مغاير للمسلك الذي تم إنشاء المربع فيه و ذلك وقت تتبع الأخطاء DEBUG.

مثلا الكود التالي سيرفع استثناء :

Timeout.SetTimeout(5000, delegate {
	myForm.Text = "Tick";
});

للتمكن من استخدام الدالة Timeout.SetTimeout للوصول إلى مربعات التحكم, يجب أولا كتابة دالة خاصة لهذا الغرض بالشكل التالي :

void SetMyFormText(string txt)
{
// إذا كان المسلك الحالي غير المسلك الذي إنشئ فيه النموذج
	if(this.InvokeRequired) {
// استدعاء لنفس الدالة
		this.Invoke((MethodInvoker) delegate {
		            	SetMyFormText(txt);
		            });
// خروج
		return;
	}
// إذا وصلنا هنا, فنحن في المسلك الصحيح و يمكننا تحديد الخاصية بكل أمان
	this.Text = txt;
}

ثانيا, استخدام الدالة Timeout.SetTimeout للمناداة على الدالة SetMyFormText :

Timeout.SetTimeout(5000, delegate {
   	SetMyFormText("Set some text after 5 seconds.");
   });

يمكن و بكل سهولة زيادة امكانية المناداة على دوال تستقبل معاملات و لكن لتبسيط الموضوع تم تجاهل ذلك.

تحياتي...

تم تعديل هذه المشاركة بواسطة محمد رضى في 15 أبريل 2011 في 10:53 — السبب: setTimeout +> SetTimeout

1
#2

السلام عليكم ورحمه الله وبركاته

اخي محمد بس حبيت التنبيه ان الداله SetTimeout الحرف الاول ب S لكن في التطبيقات تبدي ب s .. ولهذا الكود لن يعمل لان السي شارب حساسه للأحرف ... فقط لئلا يحاول بعض المبتدئين بتطبيق المثال ورؤيته لايعمل ... وشكرا على المجهود

.:: Wish to become better and better ::.

#3
VB Helper كتب:

السلام عليكم ورحمه الله وبركاته

اخي محمد بس حبيت التنبيه ان الداله SetTimeout الحرف الاول ب S لكن في التطبيقات تبدي ب s .. ولهذا الكود لن يعمل لان السي شارب حساسه للأحرف ... فقط لئلا يحاول بعض المبتدئين بتطبيق المثال ورؤيته لايعمل ... وشكرا على المجهود

هذه آفة من آفات عملية النسخ/لصق بدون تفكير :P

شكرا أخي على الملاحظة و قد قمت بتصحيح الكود :)

=======

هناك إضافة صغيرة, هي أنه يمكننا محاكاة Timer بالدالة Timeout.SetTimeout و ذلك بالمناداة على نفس الدالة في آخر الكود المنفد. مثال :

void MyMethod()
{
	Console.WriteLine("Tick");
	Timeout.SetTimeout(1000, MyMethod);
}

بمجرد تنفيد السطر التالي سيبدأ البرنامج بكتابة Tick كل ثانية و يمكن إيقاف العملية بوضع شرط لتنفيد الدالة Timeout.SetTimeout

Timeout.SetTimeout(1000, MyMethod);

مبرمجوا الجافاسكريبت متعودون على استغلال الدالة الأصلية setTimeout لعمل Animation على صفحات الويب.

#4

السلام عليكم ورحمه الله وبركاته

إضافه حلوه بس في كل فتره زمنيه سيقوم كودك بإنشاء Thread مما سيؤثر على إنجاز الجهاز .. وحسب ما قرأت سابقاً هناك عدد معين لل Thread في الجهاز لا يتجاوزها

.:: Wish to become better and better ::.

#5
VB Helper كتب:

السلام عليكم ورحمه الله وبركاته

إضافه حلوه بس في كل فتره زمنيه سيقوم كودك بإنشاء Thread مما سيؤثر على إنجاز الجهاز .. وحسب ما قرأت سابقاً هناك عدد معين لل Thread في الجهاز لا يتجاوزها

استخدامها كمحاكاة لـ Timer أمر مقبول (و لا أنصح به) في حالة كانت الفترة الزمنية كبيرة شيئا ما أي ثانية فما فوق. أما الاستعمال المفرط لها فبالتأكيد سيؤثر على كفاءة و عمل الجهاز.

أما الاستعمال الذي أراه الأمثل لها فهو القيام بتنفيذ كود يعمل في الخلفية تفاديا لتجميد واجهة المستخدم و كذلك لتبسيط الأمور.

#6

Thread قم بفحها وقفلها بعد الانتهاء من عملها مما لا ياثر علي الاداء

#7

كود الفئة Timeout في حالته تلك يؤدي إلى حذف كائن Thread مباشرة بعد نهاية تنفيذ الكود أو الدالة الممررة إلى SetTimeout. جرب فتح Task manager و تنفيد مشروع للتجربة فيه كود محاكاة التايمر بثانية واحدة و سترى أن عدد Threads الذي يظهر بجانب الملف التنفيذي لا يتعدى 1 بالإظافة إلى المسالك الخاصة بإطار الدوت نت. الشيء الوحيد الذي يزيد عن الحد هو عدد Handles الذي قد يصل إلى مئات ثم يعود للصفر بعد دقيقة أو دقيقتين.

#8

السلام عليكم ورحمه الله وبركاته

اخي محمد اريد التذكير ان هنالك فئه بنفس الاسم في System.Threading .. لأنه لو احد اضاف نفس فضاء الاسماء ستعيق توقف البرنامج

.:: Wish to become better and better ::.

مواضيع مشابهة