تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
Data Marshall
#1
الهدف:
هذا الموضوع الهدف منه توضيح واحدة من الأساليب البسيطة و السهلة لكي تتأكد ان البيانات قد تم تمريرها من داخل الكود بأسلوب أكثر أمانا وذلك من أجل تفادي الأخطاء أثناء تنفيذ البرنامج

الفكرة:
تنحصر الفكرة في استخدام عداد Count رقمي
و حين يتم تمرير اي بيانات ترتفع و تزيد قيمة هذا العداد بمقدار 1
و عندما يتم الإنتهاء من استخدام البيانات فإن العداد تقل قيمته بمقدار 1

مثال
الكود التالي عبارة عن مثال صغير وبسيط لتوضيح الفكرة

PHP كود :
       ' تخديد القيمة المبدئية للعداد
        Dim count As Integer = 0
        ' 
تعريق اي متغير 
        Dim s 
As String "visual basic"

 
       ' تعريف الناتج
        Dim resultCache As String = Nothing

        ' 
نتأكد من تمرير البيانات بشكل صحيح ثم نقوم بزيادة قيمة العداد بمقدار 1
        If Not String
.IsNullOrEmpty(sThen
            resultCache 
s
            count 
+= 1
        End 
If

 
       ' نتأكد  أن قيمة العداد لا تساوي صفرا فإن لم تكن قيمته تساوي صفر نقوم باستخدام البيانات
        ' 
ثم بعد استخدام الناتج نقوم بتقليل قيمة العداد بمقدار 1
        If count 
0 Then
            Me
.Text resultCache
            count 
-= 1
        End 
If 

الكلاس التالي يقوم بأداء نفس الفكرة المستخدمة في المثال أعلاه و الكلاس اسمه SafeCount
وهو عبارة عن كلاس  MustInherit Class يمكن توريثه لاحقا لأي كلاس أخر


PHP كود :
Public MustInherit Class SafeCount
    Implements IDisposable

    Private _count 
As Integer
    Private _lock 
As Func(Of Object) = Function() New Object
    Private _disposed 
As Boolean

    Protected Sub 
New()
 
       _count 0
    End Sub

    Protected ReadOnly Property Count 
As Integer
        Get
            Dim result 
As Integer Nothing
            SyncLock _lock
()
 
               result _count
            End SyncLock
            Return result
        End Get
    End Property

    Protected ReadOnly Property 
Empty As Boolean
        Get
            Dim result 
As Boolean
            SyncLock _lock
()
 
               result = (_count 0)
 
           End SyncLock
            Return result
        End Get
    End Property

    Protected Sub Add
()
 
       SyncLock _lock()
 
           _count += 1
        End SyncLock
    End Sub

    Protected Sub Remove
()
 
       SyncLock _lock()
 
           _count -= 1
        End SyncLock
    End Sub

    Protected MustOverride Sub Release
()

 
   Protected Overridable Sub Dispose(disposing As Boolean)
 
       If _disposed Then
            If disposing Then
                Me
.Release()
 
               Me.Remove()
 
           End If
 
       End If
 
       _disposed True
    End Sub

    Public Sub Dispose
() Implements IDisposable.Dispose
        Dispose
(True)
 
   End Sub

End 
Class ' SafeCount 

وبما أن جميع البيانات من الممكن تحويلها من و إلي Intptr أو String
سوف يتم استخدام الكلاس اعلاه و توريثه الي كلاس أخر إسمه SafePtr
حيث أن البيانات يتم تمريرها للكلاس الجديد علي هيئة IntPtr

PHP كود :
Imports System.Runtime.InteropServices

Public Class SafePtr
    Inherits SafeCount

    Implements IDisposable

    Private ptr 
As IntPtr
    Private _disposed 
As Boolean

    Public Sub 
New(ptr As IntPtr)
 
       MyBase.New
 
       Me.ptr ptr
        If Not ptr 
<> IntPtr.Zero Then
            MyBase
.Add()
 
       End If
 
   End Sub

    Public ReadOnly Property Hamdle 
As IntPtr
        Get
            Return Me
.ptr
        End Get
    End Property

    Public ReadOnly Property Valid 
As Boolean
        Get
            Return Me
.ptr <> IntPtr.Zero
        End Get
    End Property

    Protected Overrides Sub Release
()
 
       If Me.ptr <> IntPtr.Zero Then
            Marshal
.FreeHGlobal(Me.ptr)
 
           Me.ptr IntPtr.Zero
        End 
If
 
   End Sub

End 
Class ' SafePtr 

استخدام الكلاس

مثال:
PHP كود :
       Dim ptr As IntPtr = New IntPtr(Me.Handle.ToInt64)
 
       If ptr <> IntPtr.Zero Then
            Using sp 
As SafePtr = New SafePtr(ptr)
 
               If sp.Valid Then
                    Me
.Text sp.Hamdle
                End 
If
 
           End Using
        End 
If 

مثال أخر:
اقتح مشروع وأضف Label الي الفورم ثم أضف تايمر الي المشروع
و اكتب الكود بالشكل التالي

PHP كود :
Public Class Form1

    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load

        Label1
.Text DateTime.Now.ToString
        Timer1
.Start()

 
   End Sub

    Private Sub Timer1_Tick
(sender As ObjectAs EventArgsHandles Timer1.Tick

        Using sPtr 
As SafePtr = New SafePtr(System.Runtime.InteropServices.Marshal.StringToHGlobalUni(DateTime.Now.ToString))
 
           If sPtr.Valid Then
                Label1
.Text System.Runtime.InteropServices.Marshal.PtrToStringUni(sPtr.Hamdle)
 
           End If
 
       End Using

    End Sub

End 
Class 

في الحدث الخاص يالتايمر و بالرغم أن الكلاس الذي كتبناه يتم عمل Dispsoe له باستخدام جملة Using
ومع ذلك ستجد أن قيمة Label.Text تتغير مع التايمر

الكلاس SafePtr أعلاه يمكن استخدامه في اشياء كثيرة و الأمر متروك لمخيلتكم

أتمني أن يكون الكود مفيد1 للبعض منكم
تقبلوا تحياتي
Retired
الرد }}}
تم الشكر بواسطة: Fantastico , أبو نوره , ابو ليلى
#2
يهتز كبريائي عندما أقرأ أكوادك

قرأت الموضوع بعناية
لكن هذه المرة لم أفهم شيئاً
ما الذي تسعى له بالتحديد
<يعطيك العافية>
الرد }}}
تم الشكر بواسطة:
#3
الموضوع بسيط فالفكرة تنحصر في تمرير البيانات بدون أخطاء
أو تستطيع ان تعتبره نوع من Cache للبيانات

ربما الكود يبدو معقدا في ظاهره فقط بسبب استخدام IntPtr
لكن سبب ذلك أن كل شئ يمكن تحويله الي IntPtr

وقد تم استخدام IDisposable Interface في الكلاس الأصلي حتي تضمن ان البيانات التي يتم تمريرها و مهما كان نوعها يتم التخلص منها مباشرة من خلال استخدام جملة using و بالتالي لا تظل في الذاكرة

عموما في المثال الأخير في الموضوع و في الحدث الخاص بالتايمر
اكتب الكود بالشكل التالي
و ستلاحظ عند تنفيذ الكود و بالرغم أن المدخلات تساوي Nothing فإنه لا يحدث أخطاء عند اتنفيذ


PHP كود :
   Private Sub Timer1_Tick(sender As ObjectAs EventArgsHandles Timer1.Tick

        Using sPtr 
As SafePtr = New SafePtr(System.Runtime.InteropServices.Marshal.StringToHGlobalUni(Nothing))
 
           If sPtr.Valid Then
                Label1
.Text System.Runtime.InteropServices.Marshal.PtrToStringUni(sPtr.Hamdle)
 
           End If
 
       End Using

    End Sub 
Retired
الرد }}}
تم الشكر بواسطة: Amir_Alzubidy , ابو ليلى



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


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