PDA

View Full Version : گفتگو: Multi Threading - Delegate



Dariuosh
پنج شنبه 16 خرداد 1387, 16:31 عصر
سلام
اگه توضيح يا نظري راجع به Multi Threading - Delegate و مسائل مرتبط با اون دارين لطف کنيد که بيان کنيد
خواهشن اگه کدي يا Sampleايي در اين مورد ميخواهيد بزاريد VB.NET باشه و از #C و امثال اون استفاده نکنيد

در ضمن ميدونم که تا حالا بارها کم و زياد راجع به اين قضيه حرف زده شده ولي متاسفانه هيچکدوم به نتيجه مطلوبي نرسيده

هدف فقط و فقط آموزش هست و بالا بردن سطح دانش لطف کنيد بي حاشيه باشه تا انشالله بتونيم يه نتيجه خوبي بگيريم

Dariuosh
پنج شنبه 16 خرداد 1387, 16:33 عصر
لينکهاي خارج ار برنامه نويس

http://www.codeproject.com/KB/vb/Delegate.aspx
http://www.codeproject.com/KB/vb/mutithreading_for_beginer.aspx
http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
http://www.developerfusion.co.uk/show/5251/2

لينک تاپيکهايي داخلي

http://barnamenevis.org/forum/showthread.php?t=73406 (http://barnamenevis.org/forum/showthread.php?t=73406)
http://barnamenevis.org/forum/showthread.php?t=108445

Dariuosh
چهارشنبه 22 خرداد 1387, 16:09 عصر
Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.Windows.Forms
PublicClass Form2
Inherits Form
' This delegate enables asynchronous calls for setting
' the text property on a TextBox control.
DelegateSub SetTextCallback(ByVal [text] AsString)
' This thread is used to demonstrate both thread-safe and
' unsafe ways to call a Windows Forms control.
Private demoThread As Thread = Nothing
' This BackgroundWorker is used to demonstrate the
' preferred way of performing asynchronous operations.
PrivateWithEvents backgroundWorker1 As BackgroundWorker
Private textBox1 As TextBox
PrivateWithEvents setTextUnsafeBtn As Button
PrivateWithEvents setTextSafeBtn As Button
PrivateWithEvents setTextBackgroundWorkerBtn As Button
Private components As System.ComponentModel.IContainer = Nothing

PublicSubNew()
InitializeComponent()
EndSub

ProtectedOverridesSub Dispose(ByVal disposing AsBoolean)
If disposing AndAlso (components IsNotNothing) Then
components.Dispose()
EndIf
MyBase.Dispose(disposing)
EndSub

' This event handler creates a thread that calls a
' Windows Forms control in an unsafe way.
PrivateSub setTextUnsafeBtn_Click(ByVal sender AsObject, ByVal e As EventArgs) Handles setTextUnsafeBtn.Click
Me.demoThread = New Thread(New ThreadStart(AddressOfMe.ThreadProcUnsafe))
Me.demoThread.Start()
EndSub
' This method is executed on the worker thread and makes
' an unsafe call on the TextBox control.
PrivateSub ThreadProcUnsafe()
Me.textBox1.Text = "This text was set unsafely."
EndSub
' This event handler creates a thread that calls a
' Windows Forms control in a thread-safe way.
PrivateSub setTextSafeBtn_Click(ByVal sender AsObject, ByVal e As EventArgs) Handles setTextSafeBtn.Click
Me.demoThread = New Thread(New ThreadStart(AddressOfMe.ThreadProcSafe))
Me.demoThread.Start()
EndSub
' This method is executed on the worker thread and makes
' a thread-safe call on the TextBox control.
PrivateSub ThreadProcSafe()
Me.SetText("This text was set safely.")
EndSub
' This method demonstrates a pattern for making thread-safe
' calls on a Windows Forms control.
'
' If the calling thread is different from the thread that
' created the TextBox control, this method creates a
' SetTextCallback and calls itself asynchronously using the
' Invoke method.
'
' If the calling thread is the same as the thread that created
' the TextBox control, the Text property is set directly.
PrivateSub SetText(ByVal [text] AsString)
' InvokeRequired required compares the thread ID of the
' calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
IfMe.textBox1.InvokeRequired Then
Dim d AsNew SetTextCallback(AddressOf SetText)
Me.Invoke(d, NewObject() {[text]})
Else
Me.textBox1.Text = [text]
EndIf
EndSub
' This event handler starts the form's
' BackgroundWorker by calling RunWorkerAsync.
'
' The Text property of the TextBox control is set
' when the BackgroundWorker raises the RunWorkerCompleted
' event.
PrivateSub setTextBackgroundWorkerBtn_Click(ByVal sender AsObject, ByVal e As EventArgs) Handles setTextBackgroundWorkerBtn.Click
Me.backgroundWorker1.RunWorkerAsync()
EndSub
' This event handler sets the Text property of the TextBox
' control. It is called on the thread that created the
' TextBox control, so the call is thread-safe.
'
' BackgroundWorker is the preferred way to perform asynchronous
' operations.
PrivateSub backgroundWorker1_RunWorkerCompleted(ByVal sender AsObject, ByVal e As RunWorkerCompletedEventArgs) Handles backgroundWorker1.RunWorkerCompleted
Me.textBox1.Text = _
"This text was set safely by BackgroundWorker."
EndSub
#Region"Windows Form Designer generated code"
PrivateSub InitializeComponent()
Me.textBox1 = New System.Windows.Forms.TextBox()
Me.setTextUnsafeBtn = New System.Windows.Forms.Button()
Me.setTextSafeBtn = New System.Windows.Forms.Button()
Me.setTextBackgroundWorkerBtn = New System.Windows.Forms.Button()
Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker()
Me.SuspendLayout()
'
' textBox1
'
Me.textBox1.Location = New System.Drawing.Point(12, 12)
Me.textBox1.Name = "textBox1"
Me.textBox1.Size = New System.Drawing.Size(240, 20)
Me.textBox1.TabIndex = 0
'
' setTextUnsafeBtn
'
Me.setTextUnsafeBtn.Location = New System.Drawing.Point(15, 55)
Me.setTextUnsafeBtn.Name = "setTextUnsafeBtn"
Me.setTextUnsafeBtn.TabIndex = 1
Me.setTextUnsafeBtn.Text = "Unsafe Call"
'
' setTextSafeBtn
'
Me.setTextSafeBtn.Location = New System.Drawing.Point(96, 55)
Me.setTextSafeBtn.Name = "setTextSafeBtn"
Me.setTextSafeBtn.TabIndex = 2
Me.setTextSafeBtn.Text = "Safe Call"
'
' setTextBackgroundWorkerBtn
'
Me.setTextBackgroundWorkerBtn.Location = New System.Drawing.Point(177, 55)
Me.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn"
Me.setTextBackgroundWorkerBtn.TabIndex = 3
Me.setTextBackgroundWorkerBtn.Text = "Safe BW Call"
'
' backgroundWorker1
'
'
' Form1
'
Me.ClientSize = New System.Drawing.Size(268, 96)
Me.Controls.Add(setTextBackgroundWorkerBtn)
Me.Controls.Add(setTextSafeBtn)
Me.Controls.Add(setTextUnsafeBtn)
Me.Controls.Add(textBox1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
Me.PerformLayout()
EndSub'InitializeComponent
#EndRegion
<STAThread()> _
SharedSub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
EndSub
EndClass


منبع (http://msdn.microsoft.com/en-us/library/ms171728.aspx)

combo_ci
پنج شنبه 23 خرداد 1387, 01:15 صبح
http://barnamenevis.org/forum/showthread.php?t=73406

Dariuosh
شنبه 25 خرداد 1387, 17:29 عصر
می توان گفت که Delegate يکی از ويژگی های جذاب زبان برنامه نويسی VB.Net بوده که امکانات بالقوه فوق العاده ای را به اين زبان می افزايد.
Delegate چيست؟
در واقع Delegate کلاسی است که اشياء ساخته شده از آن می توانند توابع ثبت شده ( Register ) در خود را به ترتيب اجرا نمايند!. صبر کنيد!!، فرار نکنيد!!!، می دانم که اين تعريف کمی وحشت آور است ولی نگران نباشيد تا پايان بحث، موضوع کاملا شيرين خواهد شد.
برای استفاده از Delegate چهار مرحله اصلی وجود دارد که در ذيل، هر مرحله با مثال مشخص خواهد شد:
مرحله اول:
در اين مرحله اقدام به تعريف کلاس Delegate می کنيم:



Public Delegate Sub MyDelegate(ByVal n As Int16)

معنی عبارت فوق اين است که ما می خواهيم يک کلاس Delegate تعريف کنيم که اشياء آن بتوانند توابعی را در داخل خود ثبت کنند که پارامتر ورودی آنها يک عدد صحيح ( n As Int16 ) بوده و پارامتر خروجی نداشته باشند.
برای روشن شدن مطلب کلاسی به نام Employee و به شکل ذيل تعريف می نماييم:



PublicClass Employee
Public _Age As Int16
Public _FullName AsString
PublicSubNew(ByVal Age As Int16, ByVal Name AsString)
_Age = Age
_FullName = Name
EndSub
PublicSub DoIt(ByVal n As Int16)
MsgBox("I'm " & _FullName & ", I did it " & n & " times .")
EndSub
EndClass



همانگونه که مشاهده می کنيد، ما به طور عمدی در اين کلاس تابعی تعريف کرده ايم ( DoIt ) که پارامترهای ورودی و خروجی آن با آنچه که در تعريف Delegate عنوان گرديده است، مطابقت داشته باشد.
مرحله دوم:
در اين مرحله نسبت به ايجاد يک شیء از کلاس MyDelegate اقدام می کنيم:


Dim DelegateInstance As MyDelegate

در اين دستور، ما يک شیء به نام DelegateInstance از کلاس ( MyDelegate ) تعريف نموده ايم.
حال برای ادامه مسير، از کلاس Employee يک شیء به نام oEmployee به شکل ذيل ايجاد می کنيم:


Dim oEmployee As New Employee(27, "Dariuosh Eghtedari")

مرحله سوم:
در اين مرحله تنها کافی است که تابع (متد) DoIt شیء oEmployee را در شیء DelegateInstance به شکلی که در ذيل ذکر گرديده است ثبت نماييم:


DelegateInstance = New MyDelegate(AddressOf oEmployee.DoIt)

و اما مرحله چهارم (مرحله آخر):
در اين مرحله با صدا زدن ( Call) شیء DelegateInstance همراه با يک پارامتر عددی، تابع ثبت شده در داخل آن به همان پارامتر عددی مشخص شده اجرا می شوند. دقت کنيد که در اين مثال تنها يک تابع ثبت شده در داخل شیء Delegate وجود دارد.


DelegateInstance(5)

دست نگه داريد!، باور کنيد که عقل خود را از دست نداده ايم!! کاملا واضح است که به راحتی می توانستيم پس از ايجاد شی، oEmployee ، با اجرا کردن تابع Doit همراه با همان پارامتر عددی، به همان نتيجه نائل آييم. ولی دقت کنيد که هميشه اين چهار مرحله به اين شکلی که در اينجا مطرح گرديده است در کنار هم قرار نمی گيرند. نکته جالبی که در اين فنآوری وجود دارد اين است که در يک پروژه واقعی، اين چهار مرحله، هر کدام در يک قسمت از برنامه تعريف و بکارگرفته می شوند و اين مساله امکانات بسيار مفيد و جذابی را برای زبان برنامه نويسی VB.Net به ارمغان می آورد


برگرفته از وبلاگ شخصي آقاي داريوش تصديقی

Rambod
یک شنبه 26 خرداد 1387, 17:59 عصر
در مورد Multi Threading يكي از اساتيد لطف كنه و يك آموزشي چيزي بذاره. توي يه پروژه بدجوري احتياج به MultiThreading دارم ولي درست بلد نيستم.

Dariuosh
پنج شنبه 30 خرداد 1387, 13:35 عصر
همانگونه که در قسمت اول آموزش Delegate مشاهده کرديد، ما تابعي از يک شيء را در داخل يک شيء Delegate ثبت (Register) نموديم. حال در اين قسمت تصميم داريم توابع مربوط به چندين شيء را در داخل شيء Delegate ثبت نماييم تا در صورت صدا زدن (Call) شيء Delegate تمامي توابع ثبت شده در داخل آن به ترتيب اجرا شوند. براي اين منظور به مثال ذيل توجه نماييد:


Dim oEmployee1 AsNew Employee(32, "Reza Rezaee")
Dim oEmployee2 AsNew Employee(22, "Ehsan Tousi")
Dim oEmployee3 AsNew Employee(12, "Mohammad Vahidi")
DelegateInstance = New MyDelegate(AddressOf oEmployee1.DoIt)
DelegateInstance = [Delegate].Combine(DelegateInstance, New MyDelegate(AddressOf oEmployee2.DoIt))
DelegateInstance = [Delegate].Combine(DelegateInstance, New MyDelegate(AddressOf oEmployee3.DoIt))

در اين مثال، ما سه شيء از کلاس Employee ايجاد کرده و به ترتيب توابع DoIt آنها را در داخل شيء Delegate ثبت کرديم. حال در صورتيکه شيء Delegate را با پارامتر 4 اجرا نماييم، تمامي توابع اين سه شيء به ترتيب اجرا مي شوند:


DelegateInstance(4)


چهار نکته اساسي:
نکته اول: توجه داشته باشيد که هيچ لزومي ندارد شما توابع اشياء يک کلاس خاص را در داخل يک شيء Delegate ثبت نماييد. شما مي توانيد توابع مربوط به اشيائي که از کلاس هاي مختلفي ايجاد شده اند را نيز تنها به شرط اينکه پارامترهاي ورودي و خروجي آنها يکسان باشند در داخل شيء Delegate تبت نماييد.
نکته دوم: دقت کنيد که براي ثبت اولين تابع درداخل يک شيء Delegate، بايد از عملگر = (مساوي) استفاده کنيد. در صورتيکه بخواهيد توابع ديگري را نيز در داخل همان شيء Delegate ثبت نماييد، بايد از


[Delegate].Combine

براي اين منظور استفاده نماييد. پارامتر اول شيء Delegate و پارامتر دوم تابع جديدي است که قصد افزودن آن را داريد . لازم به ذکر است که اگر در اين حالت، سهوا به جاي استفاده از [Delegate].Combine از عملگر = (مساوي )استفاده کنيد، تمامي توابع از قبل ثبت شده در داخل شيء Delegate به طور خودکار Unregistered مي گردند!
نکته سوم: در صورتيکه تابعي از يک شيء (oEmployee2) را در داخل يک شيء Delegate ثبت کرده ايد و بخواهيد که شيء مذکور (oEmployee2) را از بين ببريد، ابتدا بايد تابع مربوطه را با استفاده از


[Delegate].Remove

Unregistered نموده و سپس نسبت به از بين بردن آن شيء اقدام نماييد:


DelegateInstance = [Delegate].Remove(DelegateInstance, New MyDelegate(AddressOf oEmployee2.DoIt))
oEmployee2 = Nothing


نکته چهارم: سوء تفاهم نشود! هر چند که در تمامي مثالهايي که تاکنون عنوان کرديم، تنها نسبت به ثبت توابع اشياء در داخل شيء Delegate اقدام نموديم، ولي دقت کنيد که شما قادر به ثبت توابع استاتيک (Static) کلاس ها نيز در داخل اشياء Delegate خواهيد بود و همانطور که بارها نيز عنوان کرديم تنها شرط آن اين است که پارامترهاي ورودي و خروجي اين توابع استاتيک نيز با ساختار کلاس Delegate مطابقت داشته باشند.




زنگ تفريح!:
خوب دوستان، با يک تمرين براي دست گرمي چطورين؟ حل اين تمرين نه تنها تا حدي فلسفه استفاده از Delegate را مشخص مي کند، بلکه مصداقي واقعي از بکارگيري Delegate در پروژه هاي واقعي خواهد بود:
تصور کنيد کلاس عمومي در پروژه خود تعريف کرده ايد که در داخل آن تابع استاتيکي با نام SendEmail تعبيه شده است. در جاي ديگري در برنامه خود کلاس عمومي ديگري نيز براي چاپ اطلاعات در نظر گرفته ايد و در آن تابعي با عنوان Print تعريف کرده ايد. در اين ميان کلاس ديگري نيز وجود دارد که اشياء آن وظيفه ثبت اطلاعات در بانک اطلاعاتي را با استفاده از تابعي به نام Save بر عهده دارند. تعريف اين سه تابع نيز به گونه اي است که پارامترهاي ورودي و خروجي آنها يکسان مي باشند. حال تصور کنيد که مي خواهيم يک کلاس Delegate ايجاد و شيئي از آن تعريف نماييم. سپس اين سه تابع را به ترتيب دلخواه در شيء Delegate مربوطه ثبت نماييم. دوستان عزيز، حال يکي از زيبايي هاي Delegate را در اين تمرين تجربه خواهيد کرد. با صدا زدن شيء Delegate همراه با پارامترهاي مناسب، به طور خودکار متن مورد نظر در بانک اطلاعاتي ثبت و از طريق چاپگر چاپ و نامه الکترونيکي در رابطه با اين عمليات براي مدير سيستم ارسال مي گردد!. بسيار خرسند خواهم شد که اين برنامه ساده را نوشته و در همين تاپيک قرار دهيد .