الاثنين، 10 يوليو 2017

Hash Table فى الفيجوال بيسك دوت نت

يقوم Hash Table بتخزين البيانات بشكل مزدوج عبارة عن قيمة ومفتاح. يمكننا استرداد العناصر من Hash Table بتوفير المفتاح.

الدوال الشائعة فى استخدام Hash Table
Add : اضافة 
Syntax : HashTable.Add(Key,Value)
key : قيمة المفتاح
Value : القيمة المراد اضافتها

ContainsKey : التحقق من وجود مفتاح
Synatx : HashTable.ContainsKey(key)
Key : المفتاح المراد التحقق منه

ContainsValue : التحقق من وجود قيمة
Synatx : HashTable.ContainsValue(Value)
Value : القيمة المراد التحقق منها

Remove : حذف القيمة المحددة
Syntax : HashTable.Remove(Key)
Key : المفتاح المراد حذف قيمته

المثال التالى يوضح اهم الدوال فى استخدام Hash table
Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, 
 ByVal e As System.EventArgs) Handles Button1.Click
        Dim weeks As New Hashtable
        
        weeks.Add("1", "Sun")
        weeks.Add("2", "Mon")
        weeks.Add("3", "Tue")
        weeks.Add("4", "Wed")
        weeks.Add("5", "Thu")
        weeks.Add("6", "Fri")
        weeks.Add("7", "Sat")
        'عرض عنصر واحد
        MsgBox(weeks.Item("5"))
        'البحث عن عنصر
        If weeks.ContainsValue("Tue") Then
            MsgBox("Find")
        Else
            MsgBox("Not find")
        End If
        'حذف عنصر
        weeks.Remove("3")
        'عرض كل المفاتيح والقيم
        Dim day As DictionaryEntry        For Each day In weeks
            MsgBox(day.Key  "  --  "  day.Value)
        Next
    End Sub
End Class

الأحد، 9 يوليو 2017

Array List فى الفيجوال بيسك دوت نت

ArrayList هي واحدة من بنية البيانات (Data structure)الأكثر مرونة فى vb.net collections . مع Array List يمكنك إضافة عناصر إلى المصفوفة ديناميكيا، ويقبل قيمة فارغة كقيمة صالحة ويسمح أيضا بعناصر مكررة. تسمح الفئة Collection بالوصول إلى عنصر باستخدام فهرس رقمي أو مفتاح سلسلة، ولكن يسمح Array List  فقط بفهرس رقمي.Array List مرنة لأننا يمكن إضافة عناصر دون معرفة حجم المصفوفة....

اهم الدوال المستخدمة فى Array List
Add : اضافة عنصر جديد للمصفوفة
Syntax : ArrayList.add(Item)
Item : هو العنصر الذى سيتم اضافته للمصفوفة
Dim ItemList As New ArrayList()
ItemList.Add("Item4")

Insert:اضافة عنصر جديد للمصفوفة ولكن فى موقع محدد
Syntax : ArrayList.insert(index,item)
index : موقع اضافة العنصر
Item : العنصر المراد اضافته
ItemList.Insert(3, "item6")

Remove:حذف عنصر من المصفوفة
Syntax : ArrayList.Remove(item)
Item : The Item to be Remove from ArrayList
ItemList.Remove("item2")

RemoveAt: حذف عنصر من المصفوفة عند موقع محدد
Syntax : ArrayList.RemoveAt(index)
index : موقع العنصر الذى سيتم ازالته
ItemList.RemoveAt(2)

ٍٍِSort: فرز عناصر المصفوفة
Syntax : ArrayListSort()

مثال شامل على ArrayList

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, 
 ByVal e As System.EventArgs) Handles Button1.Click
        Dim i As Integer
        Dim ItemList As New ArrayList()
        ItemList.Add("Item4")
        ItemList.Add("Item5")
        ItemList.Add("Item2")
        ItemList.Add("Item1")
        ItemList.Add("Item3")
        MsgBox("Shows Added Items")
        For i = 0 To ItemList.Count - 1
            MsgBox(ItemList.Item(i))
        Next
        'insert an item
        ItemList.Insert(3, "Item6")
        'sort itemms in an arraylist
        ItemList.Sort()
        'remove an item
        ItemList.Remove("Item1")
        'remove item from a specified index
        ItemList.RemoveAt(3)
        MsgBox("Shows final Items the ArrayList")
        For i = 0 To ItemList.Count - 1
            MsgBox(ItemList.Item(i))
        Next
    End Sub
End Class


استخدام المصفوفات فى الفيجوال بيسك دوت نت

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


المصفوفة الرقمية Integer Array
التصريح عن المصفوفة الرقمية من نوع INTEGER
Dim array As Integer() = New Integer(3) {} 
array(0) = 10
array(1) = 20
array(2) = 30
array(3) = 40

فى الكود السابق تم التصريح عن مصفوفة رقمية مكونة من 4 عناصر وقمنا باسناد القيم لها عن طريق الفهرس 
يمكن الولوج الى عناصر المصفوفة عن طريق loop على النحو التالى : - 

<span style="font-size: large;">Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim array As Integer() = New Integer(3) {} array(0) = 10 array(1) = 20 array(2) = 30 array(3) = 40 For i As Integer = 0 To array.Length - 1 MessageBox.Show(array(i)) Next End Sub End Class</span>


يمكن التصريح عن المصفوفة وأسناد العناصر لها بهذه الطريقة

<span style="font-size: large;">Dim array As Integer() = New Integer() {10, 20, 30, 40}</span>

مع ملاحظة ان الكود السابق لن يتم تحديد طول المصفوفة به وسيقوم الفيجوال بيسك بتحديده 

كيف يتم تحديد طول المصفوفة ؟
يتم استخدام الطريقة Array.Length لتحديد طول المصفوفة 

مصفوفة النصوص String Array

التصريح عن وتهيئة المصفوفة النصية 
Dim week(6) As String

ويعنى الكود السابق ان تم التصريح عن مصفوفة اسمها week ولها سبعة عناصر من نوع string

اسناد القيم للمصفوفة 
week(0) = "Sunday"

week(1) = "Monday"
.....
الدخول لعناصر المصفوفة 

Dim weekName as String = week(1)
في البرنامج التالي، نعلن مصفوفة نسميها "week" من سبعة قيم نصية وتعيين القيم السبعة كأيام في الأسبوع. الخطوة التالية هي استرداد عناصر المصفوفة باستخدام حلقة. للعثور على نهاية المصفوفة استخدمنا الدالة length ....

<span style="font-size: large;">Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim i As Integer Dim week(6) As String week(0) = "Sunday" week(1) = "Monday" week(2) = "Tuesday" week(3) = "Wednesday" week(4) = "Thursday" week(5) = "Friday" week(6) = "Saturday" For i = 0 To week.Length - 1 MsgBox(week(i)) Next End Sub End Class</span>

تغيير حجم المصفوفة 

يتم استخدام الطريقة Array.Resize لزيادة حجم المصفوفة كالتالى :-

<span style="font-size: large;">Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim sArray As Char() = New Char(4) {} sArray(0) = "A" sArray(1) = "B" sArray(2) = "C" sArray(3) = "D" sArray(4) = "E" For i As Integer = 0 To sArray.Length - 1 MessageBox.Show(sArray(i).ToString()) Next &lt;b&gt;&lt;u&gt;Array.Resize(sArray, 3)&lt;/u&gt;&lt;/b&gt; For i As Integer = 0 To sArray.Length - 1 MessageBox.Show(sArray(i).ToString()) Next End Sub End Class</span>
Array.Resize(sArray, 3)

الكود السابق يقوم بزيادة حجم المصفوفة بثلاثة عناصر

استخدام Foreach مع المصفوفات

<span style="font-size: large;">Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim array As Integer() = {10, 30, 50} 'array declaration For Each element As Integer In array MsgBox(element) Next End Sub End Class</span>
فرز المصفوفات Array Sort
تستخدم المصفوفات لتخزين مجموعات بيانات مماثلة لتجميعها كوحدة واحدة. بدلا من الإعلان عن متغيرات فردية مثل ar1 و ar2 و ar3 وما إلى ذلك، فإنك تعلن متغير مصفوفة واحد مثل الأرقام واستخدام أر (0)arr و (1)arr و (2)arr وما إلى ذلك لتمثيل المتغيرات الفردية , يتم الوصول إلى عنصر معين في المصفوفة بواسطة فهرس كما تم عرضه سابقاً .

ويتم فرز عناصر المصفوفة الرقمية عن طريق الكود التالى 
Dim arr As Integer() = New Integer() {3, 1, 4, 5, 2}
Array.Sort(arr)
For Each str As Integer In arr
    MsgBox(str) 
          Next 

وفرز عناصر المصفوفة النصية 
Dim ArrStr As String() = New String() {"c", "a", "d", "b"}
Array.Sort(ArrStr)
For Each str As String In ArrStr
    MsgBox(str)
Next
الاكواد السابقة تقوم بترتيب المصفوفة تصاعدياً ولترتيبها تنازلياً نستخدم الطريقة Array.reverse

Dim arr As Integer() = New Integer() {3, 1, 4, 5, 2}
Array.Sort(arr)
Array.Reverse(arr)
For Each str As Integer In arr
    MsgBox(str)
Next
المصفوفات النصية 

Dim ArrStr As String() = New String() {"c", "a", "d", "b"}
Array.Sort(ArrStr)
Array.Reverse(ArrStr)
For Each str As String In ArrStr
    MsgBox(str)
Next

انشاء مصفوفة باكثر من نوع بيانات muliple data type array

يمكنك إنشاء مصفوفة تحتوي على عناصر من أنواع بيانات مختلفة عند تعريف المصفوفة ككائن. بما أن System.Object هو الفئة الأساسية لجميع الأنواع الأخرى، يمكن أن يكون عنصر في مصفوفة من الكائنات مرجع إلى أي نوع آخر من الكائنات.

<span style="font-size: large;">dim mixedArray as </span><span style="font-size: large;">object()</span><span style="font-size: large;"> = new object(4)</span><span style="font-size: large;">mixedArray(0)=10 mixedArray(1)="Jack" mixedArray(2)=true mixedArray(3)=System.DateTime.Now</span>
المصفوفات الديناميكية dynamic array
المصفوفة الديناميكية يمكن زيادة عناصرها اثناء تشغيل البرنامج عندما لا نعرف عدد العناصر الذى سوف يتم انشائها بالمصفوفة 

Dim scores() As Integer

 زيادة عناصر المصفوفة وحذف قيمة جميع عناصرها

ReDim scores(1)
زيادة عناصرالمصفوفة والاحتفاظ بكل قيم عناصرها
ReDim Preserve scores(2)


مثال 

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
        Dim i As Integer
        Dim scores() As Integer

        ReDim scores(1)
        scores(0) = 100
        scores(1) = 200

        For i = 0 To scores.Length - 1
            MsgBox(scores(i))
        Next

        ReDim Preserve scores(2)

        scores(2) = 300

        For i = 0 To scores.Length - 1
            MsgBox(scores(i))
        Next
    End Sub
End Class

الثلاثاء، 4 يوليو 2017

تعدد المسارات فى الفيجوال بيسك دوت نت

هذا الموضوع يشرح موضوع تعدد المسارات فى الفيجوال بيسك دوت نت بالامثله العملية

Understanding Multi-Threading in VB.Net
فهم تعدد المسارات فى الفيجوال بيسك دوت نت
لفهم ما هو تعدد المسارات يجب اولا ان نفهم ما يحدث عند تشغيل البرنامج حيث يقوم نظام التشغيل بتحميل البرنامج فى الذاكرة ويقوم البروسيسور بتنفيذ الاكواد سطر بسطر وعند النظر لهذا المثال نجد انه سوف يتم تشغيل البرنامج وينتهى الامر ولكن عند فتح برنامج مثل notepad لا يتم الانتهاء من الاكواد حيث يوجد بداخل البرنامج loop كبيرة تقوم بالتنفيذ بشكل لا نهائى وتتحقق من مدخلات المستخدم وتقوم بتنفيذ تعليماته وعند الانتهاء من التنفيذ تعود لل loop مرة اخرى
فكر فى الكود السابق مثل الكود التالى
Public Sub Main()
         Do
         Dim msg As MESSAGE = GetMessage()
         If msg IsNot Nothing Then
             ProcessMessage(msg)
        End If
    Loop
End Sub

ال loop تقوم بالتحقق من الرسالة وعندما تجد رسالة تقوم بتمريرها لاجراء لعمل بعض العمليات عليها ولكن ماذا يحث لو ان الاجراء به loop اخر والذى سياخذ بعض الثوانى او الدقائق للتنفيذ 
مثال :-
عند محاولة تحميل ملف من الانترنت اكسبلورر تخيل ان الكود التالى هوالكود الخاص بتحميل الملف 
Public Sub DownloadFile(ByVal url As String)
        Dim fileSize As Integer = GetFileSize(url)
        Dim fileName As String = GetFileName(url)
        Dim curPos As Integer = 0
        Do While curPos < fileSize
            Dim fileData() As Byte
            Dim bytesRecd As Integer = GetNextChunk(fileData)
            curPos += bytesRecd
            appendToFile(fileName, fileData)
        Loop
End Sub

هذا ليس الكود الصحيح لتحميل ملف من الانترنت ولكن المفهوم سيكون مشابه له ولكن تخيل انه هو ماذا سوف يحدث ؟ الاجراء DownloadFile به loop والتى ستقوم بالتكرار لتحميل اجزاء الملف لذلك لو ان هذا الملف حجمه كبير سيتم تنفيذ هذا الاجراء لكثير من الوقت والانترنت اكسبلورر لن يقوم بتنفيذ اى اجراءات حتى يتم تحميل الملف بالكامل هذا معناه ان الانترنت اكسبلورر سيتوقف ولن يستجيب حتى الانتهاء من التحميل

اذن => ما هو تعدد المسارات

كثير منكم سوف يقول انه عندما يقوم بتحميل احد الملفات من المتصفح يظل المتصفح يعمل بينما يتم تحميل الملف هذا يتم عن طريق تعدد المسارات فعندما يكون هناك تحميل هذا التحميل يتم التعامل معه من خلال المسار الخاص به والمتصفح يعمل مع مسار اخر وكل منهما يعمل مستقل عن الاخر

كيف يعمل تعدد المسارات  
سنبداً بمثال بسيط الاول سنقوم باستخدام حلقة loop والتى تعد من 1 الى 100 لمحاكات عملية كبيرة مثل تحميل ملف

قم بفتح مشروع جديد وضع زر وليبل فى الفورم وفى حدث الضغط على الزر ضع الكود التالى :

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   For i = 1 To 100
       Label1.Text = CStr(i)
       Threading.Thread.Sleep(200)
    Next
End Sub
نفذ البرنامج واضغط على الزر ستجد ان البرنامج يتجمد حتى يتم الانتهاء من العد ولاحظ انه لا يتم تحديث الليبل لماذا يحدث ذلك عند الضغط على الزر يتم تنفيذ العداد لذلك فى هذه الاثناء تحديث العنوان الليبل لا يمكن تنفيذه ولا يمكن تنفيذ اى امر اخر حتى الانتهاء من الامر السابق ولا يمكن حتى تحريك الفورم من مكانه
الحل هنا هو تمرير العداد الى مسار اخر لتنفيذه 
نبداً اولا بوضع الحلقة فى اجراء مستقل


Private Sub Count(ByVal Max As Integer)
    For i = 1 To Max
      Label1.Text = CStr(i)
      Threading.Thread.Sleep(200)
    Next 
End Sub
الان لدينا العداد داخل اجراء خاص به وفى حدث الضغط على الزر نكتب الكود التالى 


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   Dim t1 As New Threading.Thread(AddressOf Count)
   t1.Start(100)
End Sub
السطر الاول يقوم بعمل مسار جديد thread وتمرير الاجراء المراد تنفيذه عند طريق AddressOf لكن من المهم هنا ان نعرف انه غير مسموح الا باجراء له وسيط واحد فقط
السطر الثانى يبدأ المسار ويأخذ وسيط واحد الخاص بالاجراء 

ملاحظة
لو لديك اختيار  Option Strict On اضف هذا الا جراء


Private Sub Count(ByVal Max As Object)
    If TypeOf Max Is Integer Then
       Count(CInt(Max))
    End If
End Sub
والسبب وراء اضافة هذا الاجراء لان المشيد الخاص بالمسار يتوقع اجراء ياخذ وسيط واحد واختيار option strict  لن يسمح لان يتم تمرير وسيط من نوع integer الان نفذ البرنامج
الان سيظهر الخطأ التالى 
والان ما معنى الخطا الظاهر وما سببه , هذا الخطا ظهر ليمنع كارثه محتمله تذكر ان ال UI له المسار الخاص به و ال UI هو كل ما تراه امامك فى الفورم الزر والليبل وكل الادوات التى تضعها مسئول عنها UI ومسئول عن كل الاحداث الخاص بهم ولذلك فهو يقوم بمنع اى مسار اخر بالتحكم فى هذه الادوات والا سوف يسبب ذلك عدم ثبات فى البرنامج ولذلك يقوم الفيجوال بيسك بمنع تغيير الليبل من مسار اخر .
الطريقة الصحيحة لعمل ذلك هو طلب من ال UI  تعديل الليبل ولو ان هناك اوامر اخرى جارى تنفيذها عند الطلب سيتم جدولة هذا الطلب حتى يتم الانتهاء من الاعمال المسندة اليه ويقوم بتحديث الليبل
 كيف يمكن عمل هذا الطلب ...
نقوم بعمل الاجراء التالى لتغيير الليبل 


Private Sub SetLabelText(ByVal text As String)
   If Label1.InvokeRequired Then
     Label1.Invoke(New Action(Of String)(AddressOf SetLabelText), text)
  Else
   Label1.Text = text
     End If
End Sub
فى هذا الاجراء تم طلب الخاصية InvokeRequired لل label لتحديد هل يتم استخدام الليبل من المسار الحالى لل UI ام مسار خارجى ويعطى القيمة true فى حالة لو انه مسار خارجى

 Label1.Invoke(New Action(Of String)(AddressOf SetLabelText), text)

السطر السابق يقوم بتنفيذ الطلب لل UI لتغيير الليبل عن طريق الاجراء SetLabelText ولكن بدلا من التنفيذ على المسار الاخر بدلاً من ذلك سيتم تنفيذه على المسار الخاص بال UI
الخاصية InvokeRequired ستعيد القيمة False والتى ستنفذ عملية تغيير قيمة الليبل هذا هو المفتاح لان ال Ui thread سينفذ الاجراء فقط عندما لا يكون مشغول بتنفيذ اجراءات اخرى 

  Private Sub Count(ByVal Max As Integer)
          For i = 1 To Max
              SetLabelText(CStr(i))
              Threading.Thread.Sleep(200)
          Next
   
End Sub
لقد قمنا باستخدام SetLabelText  لتغيير الليبل بدلا من محاولة تغييره مباشرة 
الان نجحنا بانشاء تطبيق تعدد مسارات بسيط
شئ واحد باقى . نفذ البرنامج واضغط على الزر واغلق الفورم قبل انتهاء Count لو قمت بعمل هذا ستلاحظ ان البرنامج لم يتوقف فعلياً لان المسار لا زال يعمل .
عادة نحتاج ان نجعل المسار يعمل بالخلفية background thread للعمليات مثل هذه لان هذه المسارات يتم انهائها عندما يتم انهاء البرنامج وذلك يجب عمل التعديلات التالية 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
          Dim t1 As New Threading.Thread(AddressOf Count)
   
          t1.IsBackground = True
   
          t1.Start(100)
      End Sub
هذه الطريقة الاساسية للتعامل مع تعدد المسارات فى الفيجوال بيسك دوت نت ا
فيما بعد ان شاء الله سيتم شرح موضوع Thread Pools
 
 الملف المرفق به مشروع على ما تم شرحه 







جميع الحقوق محفوظة © 2019 الحقيبة البرمجية لمبرمجى VB.NET