تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
[VB.NET] تايمر جديد اسرع بأضعاف من التايمر العادي ؟!
#1
Lightbulb 
السلام عليكم ورحمة الله وبركاته



قبل قليل كنت اجرب شي وهو عمل تايمر عن طريق BackgroundWorker وتفاجئت عندما رأيت انه اسرع من التايمر العادي وحبيت اضع هذا المقال ان شاء الله يفيدكم , بالرغم ان كلامها نفس السرعة عند وضع [b]interval يساوي 1000 لكن ممكن وضع قيمة 0 للفئة الجديدة وهي اصلا اسرع عندما كلاهما 1 بكثير[/b]
 





اولآ سنقوم بعمل التايمر ثم نقارن بين السرعتين:


نفتح مشروع جديد ونضيف كلاس جديد ونسميه Mytimer





الان انسخ الكود الذي عملته وهو اداة تشبه التايمر الى الكلاس


كود :
Imports System.ComponentModel

Public Class MyTimer
   Inherits Component
   Private WithEvents Background As New BackgroundWorker _
   With {.WorkerSupportsCancellation = True}
   Event Tick(ByVal sender As Object, ByVal e As EventArgs)

   Private En As Boolean = False
   Property Enabled() As Boolean
       Get
           Return En
       End Get
       Set(ByVal value As Boolean)
           En = value
           If value = True Then
               If Not Background.IsBusy Then
                   Background.RunWorkerAsync()
               End If
           Else
               If Background.IsBusy Then
                   Background.CancelAsync()
               End If
           End If
       End Set
   End Property

   Private Intrvl As Integer = 100
   Property Interval() As Integer
       Get
           Return Intrvl
       End Get
       Set(ByVal value As Integer)
           Intrvl = value
       End Set
   End Property

   Public Sub Start()
       Enabled = True
   End Sub
   Public Sub _Stop()
       Enabled = False
   End Sub


   Private Sub Background_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Background.DoWork
       RaiseEvent Tick(Me, New EventArgs)
   End Sub

   Private Sub Background_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Background.RunWorkerCompleted
       wait(Interval)
       If Me.Enabled Then
           Background.RunWorkerAsync()
       End If

   End Sub

   Public Sub New()
       System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
   End Sub

   Private Sub wait(ByVal interval As Integer)
       On Error Resume Next
       Dim sw As New Stopwatch
       sw.Start()
       Do While sw.ElapsedMilliseconds < interval
           Application.DoEvents()
       Loop
       sw.Stop()
   End Sub
End Class

واعمل Build للمشروع ستلاحظ ظهور الاداة كما في الصورة







نضيف الاداة على الفورم ونضيف Timer العادي و2 ليست بوكس وزر بوتون و2 ليبل كما في الصورة
ونختار لكلا التايمرين interval=1




الان نضع هذا الكود في الفورم

كود :
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Timer1.Start()
       MyTimer1.Start()
   End Sub

   Dim a As Integer = 0
   Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
       If a = 400 Then
           Timer1.Enabled = False
           Label2.Text = "Timer: 1"
       End If
       ListBox2.Items.Add(a)
       a += 1
   End Sub
   Dim i As Integer = 0
   Private Sub MyTimer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyTimer1.Tick
       If i = 400 Then
           MyTimer1.Enabled = False
           Label1.Text = "MyTimer: 1"
       End If
       ListBox1.Items.Add(i)
       i += 1
   End Sub




وكما تلاحظون تعمدت تشغيل التايمر العادي قبل الكلاس الذي انشأته لكن ستلاحظون فرق كبير بالسرعة حيث تقريبا عندما وضعت Interval للكلاس يساوي 15 تقريبا تساوت السرعتان

ان شاء الله يكون موضوع مفيد للبعض وتحياتي
الرد
#2
موضوع جميل جعله الله في ميزان حسناتك .

PHP كود :
   Dim mythr As Threading.Thread
    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        mythr 
= New Threading.Thread(AddressOf MyTimerSub)
 
       mythr.Start()
 
   End Sub
    Function MyTimerSub
()
 
       Do
            Threading
.Thread.Sleep(1000)
 
           Lbl_Time.Text Now.ToString("hh:mm:ss tt")
 
       Loop
    End 
Function
 
   Private Sub Form1_FormClosing(sender As ObjectAs FormClosingEventArgsHandles Me.FormClosing
        mythr
.Abort()
 
   End Sub 

ساعة بدون اداة التايمر .
الرد
#3
(22-11-19, 06:24 AM)asemshahen5 كتب : موضوع جميل جعله الله في ميزان حسناتك .

PHP كود :
   Dim mythr As Threading.Thread
    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        mythr 
= New Threading.Thread(AddressOf MyTimerSub)
 
       mythr.Start()
 
   End Sub
    Function MyTimerSub
()
 
       Do
            Threading
.Thread.Sleep(1000)
 
           Lbl_Time.Text Now.ToString("hh:mm:ss tt")
 
       Loop
    End 
Function
 
   Private Sub Form1_FormClosing(sender As ObjectAs FormClosingEventArgsHandles Me.FormClosing
        mythr
.Abort()
 
   End Sub 

ساعة بدون اداة التايمر .

ماشاء الله استاذ عاصم ربي يحفظك

لي سؤال لماذا المسارات لاتعمل لدي الا اذا وضعت عدم تحقق للمسارات
كود :
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
هل بسبب لان الفيجوال لدي 2008؟

وسؤالي الاخر ماهو سر الكود ؟ لان انا في الاول استخدمت
كود :
Threading.Thread.Sleep()
لكن في كل مرة استخدمها لدي تتوقف مسارات التنفيذ الاخرى , تأثر على مسارات البرنامج لكن في كودك لم تتوقف بقية المسارات
واذا لاحظت اني استخدمت Stopwatch بدل عنها

اسأل الله ان يزيدك من علمه وشكرآ لك
الرد
#4
لكل طريقة محاسنها و مساوئها انت تستخدم اداة BackgroundWorker انا استخدمت كود Thread عادي .

عندي لايتم التحقق عندك يتم بسبب الاداة المستخدمة و نفس الشيء بالنسبة للسؤال الثاني .

مساوء طريقتي اني لا استطيع اغلاق الفورم دون كتابة : mythr.Abort() في كود الاغلاق .
الرد
تم الشكر بواسطة: 3booody , محمد كريّم , sendbad100 , حريف برمجة
#5
غريب مع اني سواء استخدمت Thread او اداة ال BackgroundWorker نفس رسالة الخطأ تظهر
على العموم اشكرك استاذي الغالي ربي يزيدك من علمه ويحفظك
الرد
تم الشكر بواسطة: asemshahen5 , محمد كريّم , sendbad100 , حريف برمجة
#6
(22-11-19, 12:11 PM)3booody كتب : ماشاء الله استاذ عاصم ربي يحفظك

لي سؤال لماذا المسارات لاتعمل لدي الا اذا وضعت عدم تحقق للمسارات
كود :
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
هل بسبب لان الفيجوال لدي 2008؟

قبل قليل واجهت نفس المشكلة ووجدت الحل في Invoke()

المشكلة تحدث بسبب محاولة thread الوصول إلى control موجود على thread آخر

جرب هذه الطريقة (كود محول وغير مجرّب) :
كود :
Invoke(CType(Function()
                        Lbl_Time.Text = Now.ToString("hh:mm:ss tt")
End Function, Action))


طرق أخرى (C#) :
https://stackoverflow.com/q/10775367/3814729
https://stackoverflow.com/q/142003/3814729

الرد
#7
السلام عليكم

الله يعطيك الصحة والعافية اخي /3booody

لو طرحنا فكرة التايمر الجديد  للنقاش

 بصراحة شدني العنوان كيق تايمر اسرع لانه يجب ان تعطية القيمة كي ينفذ كل فترة زمنية معروفة ك دقيقة او ثانية او اقل. المهم تكون حسابها. 

لذلك اعتقد التايمر الجديد  فكرتة بديل او ك  For loop .
ام ماذا؟
الرد
#8
(24-11-19, 01:39 AM)محمد كريّم كتب : قبل قليل واجهت نفس المشكلة ووجدت الحل في Invoke()

المشكلة تحدث بسبب محاولة thread الوصول إلى control موجود على thread آخر

جرب هذه الطريقة (كود محول وغير مجرّب) :
كود :
Invoke(CType(Function()
                        Lbl_Time.Text = Now.ToString("hh:mm:ss tt")
End Function, Action))

فكرة ممتازة جزاك الله خيرآ اخي
فعلآ كما ذكرت اساسآ لايظهر الخطأ الا اذا وضعت كونترول

(24-11-19, 05:46 AM)sendbad100 كتب :
السلام عليكم

الله يعطيك الصحة والعافية اخي /3booody

لو طرحنا فكرة التايمر الجديد  للنقاش

 بصراحة شدني العنوان كيق تايمر اسرع لانه يجب ان تعطية القيمة كي ينفذ كل فترة زمنية معروفة ك دقيقة او ثانية او اقل. المهم تكون حسابها. 

لذلك اعتقد التايمر الجديد  فكرتة بديل او ك  For loop .
ام ماذا؟

نعم اخي الفاضل بالضبط وكلنا نعرف ان سر التأخر هوا دالة Wait التي وضعتها وسرعتها تعتمد على ال Loop وهي تستطيع اعتبارها حلقة تكرارية تتحكم في سرعتها وتستطيع تشغيلها واطفائها بأي وقت , وهي بالفعل تكون متساوية السرعة عند الثانية او نصف ثانية او الاكثر منهما
لان احيانآ نحتاج نستخدم تايمر بأقصى سرعته وربما حتى سرعته لاتؤدي الغرض الذي نريد واذكر أني اجبت على سؤال لاحد الاخوة كان يستخدم تايمر ليأخذ فريمات صور متتالية بأقصى سرعة للتايمر و لو يستخدم هذه الاداة راح يكون شغلو اسرع لالتقاط الصور من الكود الذي اعطيته هو في السابق

والحمدلله انها كانت مشاركة حلوه لان تحلو المشاركة بكثرة نقاشاتها
اسأل الله ان يديم هذا الجمع الطيب
الرد
#9
هكذا المبدعون أمثال أخى الغالى 3booody 
يصنعون من المستحيل مُمكناً بل سهلاً مُيسراً ومن الشيئ العادى شيئاً عظيماً ذا قيمة...
الرد
تم الشكر بواسطة: asemshahen5 , 3booody , محمد كريّم , sendbad100
#10
(27-11-19, 11:22 PM)ابو روضة كتب :
هكذا المبدعون أمثال أخى الغالى 3booody 
يصنعون من المستحيل مُمكناً بل سهلاً مُيسراً ومن الشيئ العادى شيئاً عظيماً ذا قيمة...

كلامك الجميل هو القيم اخي الغالي ابو روضة اشكرك واسأل االله التوفيق لك
الرد
تم الشكر بواسطة: ابو روضة , asemshahen5 , محمد كريّم , sendbad100


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
Rainbow [VB.NET] كلاس ResizeControls وطريقة جديد ومميزة لتكبير وتصغير ادوات الفورم تلقائيا الماجيك مسعد 8 2,955 01-10-18, 03:03 AM
آخر رد: LEO
  (عنوان معدل) عمل شاشة البداية بدون كود ولا تايمر ولا اى حاجه mero5000 5 2,043 23-08-15, 12:50 AM
آخر رد: lolo queen
  كونترول جديد من مايكروسوفت MsChart Control RaggiTech 1 1,379 05-10-12, 03:04 PM
آخر رد: RaggiTech
  نوع بيانات جديد (تاريخ) RaggiTech 0 911 05-10-12, 03:34 AM
آخر رد: RaggiTech
  جديد 2010- اكتب الكود الذي سيستخدم فئتك ثم قم بإنشائها RaggiTech 0 956 03-10-12, 12:27 PM
آخر رد: RaggiTech
  الطرائق المُوَسِّعة Extension Methods من جديد VB2008 RaggiTech 1 884 02-10-12, 07:31 PM
آخر رد: RaggiTech
  الاستدلال المحلي على النوع Local Type Inference من جديد VB2008 RaggiTech 0 970 02-10-12, 09:43 AM
آخر رد: RaggiTech
  الأنواع المجهولة Anonymous Types، من جديد VB 2008 RaggiTech 0 812 02-10-12, 08:57 AM
آخر رد: RaggiTech
  أفضل طريقة لإنشاء كائن جديد - شارك في النقاش RaggiTech 1 842 01-10-12, 11:07 PM
آخر رد: RaggiTech
  Private Text Encryption -خدمة للمبرمجين في جديد عالم التشفير- RaggiTech 0 1,273 01-10-12, 06:36 PM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم