PDA

View Full Version : مقاله: آموزش جامع Threading و مباحث مربوطه مثل synchronization



محسن شامحمدی
جمعه 29 بهمن 1389, 20:25 عصر
با سلام خدمت دوستان
هدف بنده از ایجاد این تاپیک آموزش کامل برنامه نویسی چند نخی در vb.net هستش.
برنامه نویسی چندنخی در ابتدا بسیار ساده بنظر می رسد ولی این را بدانید که این روش از برنامه نویسی ضمن اینکه برنامه شما را به شدت قوی و سریع و انعطاف پذیر می کند. نیاز به دقت بسیار زیادی در کدنویسی نیز دارد.

Thread چیست؟
برای اینکه مفهوم Thread را دریابیم ابتدا باید متوجه بشویم که برنامه ها در پردازشگر به چه صورتی اجرا می شوند.
در گذشته همیشه در آن واحد امکان انجام یک کار وجود داشت (سیستم عامل داس را به یاد آورید) که پردازشگر منتظر می ماند تا به او پردازشی بدهند تا پردازش کند
ولی با پیشرفت های نرم افزاری دانشمندان به این نتیجه رسیدند که این کار یعنی اسراف در منابع.چون در بسیاری از مواقع پردازش برنامه اجرایی پایان یافته و دیگر به پردازش نیاز ندارد و پردازشگر بیکار می ماند.
از این رو روشی را ایجاد کردند که چندین کار به پردازشگر بدهند و پردازشگر با زمانبندی خاصی آن ها را انجام بدهد. این یعنی مثلا سه تا کار داریم. که پردازش هر کدام نیاز به 3 ثانیه زمان دارد.
حال پردازشگر به مدت 1 ثانیه کار اول را انجام می دهد بعد به سراغ دومین کار می رود و به همین ترتیب.و بعد این کار را آنقدر تکرار می کند تا پردازش این کارها به اتمام برسد.
به این روش سیستم multi tasking گویند.
کمی جلوتر رفته و می بینیم که در این حالت چند نرم افزار بطور همزمان وجود دارند که پردازشگر در هر ثانیه وقتی به آن ها اختصاص می دهد.ولی در بعضی شرایط ممکن است اختصاص دادن یک واحد زمان به برنامه شما کم باشد.در این شرایط شما می توانید تعداد اجرای کد برنامه تان را توسط پردازشگر بیشتر کنید.در این حالت باید از Thread ها استفاده کنیم.
ما می توانیم برای برنامه مان چندین Thread بسازیم که هر کدام در برنامه وظیفه ای را انجام دهند.
فواید استفاده از Thread
تصویر زیررا ببینید:
http://vbupload.persiangig.com/image/process%20list.jpg
همانطور که درتصویر می بینید در حافظه Ram سه پردازش وجود دارند:
Explorer.exe با 5 Thread
Virus.exe با 1 Thread
Firefox.exe با 7 Thread
همانطور که می بینید در بطور همزمان چند برنامه اجرا شده اند که هر کدام از آن ها دارای یک یا چندین Thread می باشند.
برای مثال پردازش Firefox.exe را در نظر بگیرید:
یکی از Threadهای آن برای دریافت متن html از اینترنت ،یکی برای ترجمه متن html به شکل گرافیکی،یکی برای دریافت تصاویر صفحه،یکی برای ... که بصورت همزمان انجام می شوند.
حال کمی به عقب برگردیم و در نظر بگیریم که این ها همزمان اجرا نشوند بلکه ابتدا یک کار تمام شود بعد کار دیگر.
در این حالت ابتدا باید تمامی صفحه html از اینترنت دریافت شود.
سپس تمامی تصاویر آن.
سپس تمامی متون html به شکل گرافیکی روی صفحه رسم شوند.
در نتیجه نمایش یک صفحه عادی ممکن است چندین دقیقه به طول بیانجامد!

به طور کلی در ذیل به چند فایده برنامه نویسی MultiThread نسبت به حالت Single Thread اشاره می کنیم:
تکنیک های چندنخی می تواند پاسخ گویی رابط کاربری برنامه شما را در مقابل کاربر بیشتر کند.در واقع در حالی که یک سری عملیات در پس زمینه اجرا می شوند،رابط کاربری برنامه شما فعال و پاسخ گو باقی می ماند
در حالی که یک Thread مشغول است پردازشگر می تواند به کار Thread های دیگر بپردازد.
در حالی که پردازش های طولانی در پس زمینه اجرا شده است پردازش های کم مصرف می توانند به راحتی اجرا شوند.
پردازش ها در هر لحظه ای از زمان می تواند Pause یا حتی به طور کامل متوقف شوند!
شما می توانید اولویت هر Thread ای را به طور جداگانه با مقدارهای کم و زیاد تنظیم کنید که این کار باعث افزایش کارایی و قدرت برنامه می شود.

اکنون که دریافتیم Thread چیست،نوبت استفاده از آن است:
نحوه تعریف یک Thread:
ابتدا یک تابع می سازیم و کدهایی که قصد اجرا کردن آن به صورت همزمان با برنامه اصلی را داریم را در آن می نویسیم.
و سپس یک شی از کلاس Thread تعریف می کنیم.
مثلا:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t AsNew Threading.Thread(AddressOf ConcurrentWork)
t.Start()
EndSub

PrivateSub ConcurrentWork()
WhileTrue
'some works
EndWhile


EndSub

در اینجا یک شی از کلاس Thread تعریف کردیم و آدرس تابع ConcurrentWork را به آن دادیم و بعد با استفاده از متد Start آن این کد را در یک واحد پردازشی جدا اجرا کردیم.
همانطور که می بینید با اینکه این حلقه بی نهایت است ولی برنامه دچار حالت قفل شدن نمی شود.
دلیل این است که برنامه و متعلقات آن در یک واحد پردازشی و حلقه بی نهایت ما در یک واحد پردازشی جداگانه اجرا می شود.
اکنون بر دکمه ضربدر برنامه کلیک کنید تا برنامه بسته شود.اکنون خواهید دید فرم اصلی (Thread اصلی)برنامه بسته می شود ولی Thread ای که توسط ما ساخته شد و حلقه بی نهایت در آن اجرا می شود بسته نشده است.
برای این که چنین شرایطی به وجود نیاید کافیست خاصیت IsBackground شی Thread را True تنظیم کنید.

درس بعدی:معرفی اجزای کلاس Thread

محسن شامحمدی
دوشنبه 02 اسفند 1389, 17:50 عصر
از آنجایی که به طور مختصر با thread و طریقه تعریف آن آشنا شدیم اکنون با متدها و خواص این کلاس آشنا می شویم:
متدهای مهم کلاس Thread:
http://lh3.googleusercontent.com/-W5ZtQcwvnbM/UnZ7GJhYHEI/AAAAAAAAAJ0/j9xmRAmBT-w/s1024/hafezup.ir_1383496531.jpg


خواص مهم کلاس Thread:
http://lh3.googleusercontent.com/-fhEJ0gFdItw/UnZ6wjVWqEI/AAAAAAAAAJs/rXGLdHLCFMM/s1024/hafezup.ir_1383496444.jpg

خاصیت priority یکی از مقادیر زیر را می تواند داشته باشد.

Lowest
BelowNormal
Normal
AboveNormal
Highest


خاصیت ThreadState یکی از خاصیت های زیر را می تواند داشته باشد.

http://lh3.googleusercontent.com/-s9ZPYAfmS7E/UnZ7JJ-AfHI/AAAAAAAAAJ8/sNLIWTC_TR0/s1024/hafezup.ir_1383496543.jpg

درس بعدی:
Pause و Play کردن یک پردازش(thread) دقیقا شبیه یک فیلم!!!

محسن شامحمدی
سه شنبه 03 اسفند 1389, 17:03 عصر
گاهی در برنامه نیاز داریم که یک پردازش را در وسط انجام کار متوقف(Pause) کنیم و بعدا ادامه آن را اجرا کنیم.
مثلا:


· در آنتی ویروس ها
· برنامه های فشرده سازی فایل
· برنامه کپی فایل
· نرم افزار Image گرفتن از Cd و Dvd
· نرم افزارهای مبدل(هر نوع فایل به نوع دیگر)

و بطور کلی خیلی از کارها زمانبر هستند و همچنین پردازشگر را به شدت مشغول می کنند.در این موارد بهتر است که امکان توقف موقت پردازش را برای کاربر فراهم کنیم.
حال نحوه کار را با ذکر یک مثال شرح می دهیم:
لوازم مورد نیاز:


· متد suspend(برای توقف Thread)
· متد Resume (برای ادامه اجرای یک Thread متوقف شده)
· خاصیت Threadstate(برای تشخیص وضعیت Thread مورد نظر)

برنامه مورد نظر: برنامه تولید اطلاعات متنی و ذخیره در فایل با قابلیت Pause و Resume
تصویری از محیط برنامه:

http://lh5.googleusercontent.com/-X2jG7w57iRE/UnZ7i9dX4cI/AAAAAAAAAKE/ZL9VtAuucQ8/s1024/hafezup.ir_1383496646.jpg
سورس برنامه:(سورس کامل برنامه ضمیمه شده است.)


Public Class Form1
Dim t As Threading.Thread

Private Sub Btnstart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnstart.Click
Control.CheckForIllegalCrossThreadCalls = False
t = New Threading.Thread(AddressOf Create_big_file)
t.IsBackground = True
t.Start(txtfilename.Text.Trim)
btnstart.Enabled = False
btnpause.Enabled = True
btnabort.Enabled = True
End Sub

Private Sub Create_big_file(ByVal FileName As String)
Dim fs As New IO.StreamWriter(FileName)
Dim i As Decimal
While True
fs.WriteLine("www.Barnamenevis.org " + "Line: " + i.ToString)
fs.Flush() 'save this line
lblstatus.Text = "Line: " + i.ToString
i += 1
End While
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim cdl As New SaveFileDialog
cdl.Filter = "Text Files|*.txt"
If cdl.ShowDialog = Windows.Forms.DialogResult.OK Then
txtfilename.Text = cdl.FileName
End If
End Sub

Private Sub btnpause_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnpause.Click
t.Suspend()
btnpause.Enabled = False
btnresume.Enabled = True
End Sub

Private Sub btnresume_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnresume.Click
t.Resume()
btnresume.Enabled = False
btnpause.Enabled = True
End Sub

Private Sub btnabort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnabort.Click
If t.ThreadState = Threading.ThreadState.Background + Threading.ThreadState.Suspended Then
MsgBox("هنگامی که یک نخ در حالت توقف است نمی توان آن را نابود کرد", MsgBoxStyle.Exclamation)
ElseIf t.ThreadState = Threading.ThreadState.Background + Threading.ThreadState.Running Then
t.Abort()
MsgBox("Thread Aborted By User!", MsgBoxStyle.Critical) : End
End If

End Sub

End Class


مزایای تولید این برنامه با Thread در مقایسه با مدل بدون Thread:


· قابلیت Pause و Resume برنامه توسط کاربر
· قفل نشدن فرم برنامه هنگام پردازش
· سرعت بالاتر نسبت به حالت تک نخی
درس بعدی: همزمان سازی Thread ها

محسن شامحمدی
چهارشنبه 04 اسفند 1389, 17:00 عصر
فکر کنم این تاپیک زیاد استقبال کننده نداره درسته؟
در هر صورت من ادامه آموزش رو می نویسم و می ذارم انشاالله که اهل فن استفاده کنند.
خب حالا رسیدیم سروقت یکی از مهمترین مباحث برنامه نویسی MultiThread به نام Synchronization
در برنامه نویسی چندنخی شما می توانید به نحوه اجرا و ترتیب اجرای Thread های تان نظم ببخشید.
ما به 2 دلیل از تکنیک های همزمان سازی استفاده می کنیم:


برای کنترل کردن صریح ترتیب اجرای Thread ها.و تنظیم ترتیب اجرای کد Threadهای مختلف



برای جلوگیری از مشکلاتی که می تواند هنگامی که دو Thread در یک زمان از یک منبع مشترک استفاده می کنند،اتفاق بیفتد

برای مثال شما از همزمان سازی می توانید در مواردی استفاده کنید که در یک Thread اطلاعاتی از سرور گرفته شود و در Thread دیگر آن اطلاعات در رابط کاربری نمایش داده شود.
استفاده از متد Join برای ترتیب دادن به اجرای Thread ها
با استفاده از متد join می توان به ترتیب اجرای Threadها نظم داد.
مثلا:


Sub JoinThreads()

Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)

Thread1.Start()

Thread1.Join() ' Wait for the thread to finish.

MsgBox("Thread is done")

End Sub

به تصویر زیر دقت کنید:
http://vbupload.persiangig.com/image/join%20threads.jpg
تکنیک های پیشرفته همزمان سازی
دات نت فریمورک چندین راه برای همزمان سازی Threadها دارد که در ذیل با آن ها آشنا می شویم.

AutoResetEvent

Interlocked

ManualResetEvent

Monitor

Mutex

ReaderWriterLock

Timer

WaitHandle
حال برای اینکه متوجه بشویم که همزمان کردن Threadها چه سودی دارد نگاهی به مثال زیر می کنیم.
یک دکمه بر روی فرم بکشید و کدهای زیر را در آن وارد کنید.


Control.CheckForIllegalCrossThreadCalls = False

Dim t1 As New Threading.Thread(AddressOf ToRight)

Dim t2 As New Threading.Thread(AddressOf ToLeft)

t1.Start()


t2.Start()


سپس متدهای زیر را در کد قرار دهید.
Private Sub ToRight()
For i = 1 To 100
Button1.Left += 1
Me.Refresh()
Next
End Sub

Private Sub ToLeft()
For i = 1 To 100
Button1.Left -= 1
Me.Refresh()
Next


End Sub



سورس با نام BadMove ضمیمه شده است.
حال برنامه را اجرا کنید و بر روی دکمه کلیک کنید.
نتیجه کار با کد هم خوانی ندارد!
در کد، نوشته بودیم که یک Thread آن را 100 واحد به راست برده و Thread دیگر 100 واحد به چپ. پس بعد از اجرای برنامه،دکمه دقیقا باید سر جای قبلی خود قرار بگیرد ولی قرار نگرفت.دلیل چیست؟؟؟؟
دلیل اینست که یک سری از کدها چون با یک منبع مشترک و در یک زمان اجرا می شود به خوبی اجرا نمی شوند.برای حل مشکل باید از تکنیک های همزمانی استفاده کنیم.
در پایین با استفاده از هر یک از اشیا معرفی شده مشکل را حل می کنیم.
آشنایی با اشیا همزمان سازی
Mutex
این شی در هر لحظه می تواند فقط در یک Thread فعال باشد و در بقیه Threadها غیرفعال می شود که این ویژگی سبب می شود که ما مطمئن شویم که کدههایمان بصورت همزمان فقط و فقط در یک Thread اجرا می شود.
این شی دو متد مهم دارد که عبارتند از:
WaiteOne: شی mutex را در این Thread فعال می کند
ReleaseMutex: شی mutex را آزاد می کند
در فایل edit with mutexbad move مشکل مزبور با استفاده ازاین شی حل شده است.
Monitor
این شی دو متد مهم دارد که عبارتند از:
Enter: یک شی را گرفته و آن را قفل می کند
Exit: یک شی را گرفته و آن را آزاد می کند
در فایل edit with monitorbad move مشکل مزبور با استفاده ازاین شی حل شده است.
Synclock
ویژوال بیسیک تضمین می کند که هر کدی که در این بلوک قرار گیرد بطور همزمان فقط در یک Thread اجرا می شود.

در فایل edit with synclockbad move مشکل مزبور با استفاده ازاین شی حل شده است.
تمرین: برای درک کامل مفهوم همزمان سازی به شدت پیشنهاد می کنم که این برنامه را دانلود کنید و با استفاده از تکنیک های همزمان سازی،مشکل دسترسی همزمان دو Thread به یک شی را حل کنید.
درس بعدی: اجرای تایمر ولی در یک Thread دیگر!!!

محسن شامحمدی
چهارشنبه 04 اسفند 1389, 19:34 عصر
دوستان حالا که آموزش بالا رو یاد گرفتید یک پروژه واستون می ذارم که خودتون رو محک بزنید.
مشکل این پروژه به راحتی با همزمان سازی حل می شه.
در حال حاضر به دلیل اینکه 2 تا ترد همزمان به شی دسترسی پیدا می کنن، Exception پرتاب می کنه.

دوستان هر کی مشکل رو حل کرد (با هر تکنیکی باشه فرقی نداره)بیاد و اینجا اعلام کنه و توضیح هم بده چطور شد که مشکل درست می شد و چطور مشکل رو حل کرد.

دوستان اگر تا 2 یا 3 روز دیگه جوابشو نداده بودید، حتما فایل تصحیح شده ش رو می ذارم ببینید چطوریه.

alimanam
چهارشنبه 04 اسفند 1389, 20:05 عصر
با سلام

دوست عزیز تمرینی که فرمودین رو حل کردم :افسرده: در مورد توضیحات هم که خودتون استاد ما هستین و در پست شماره 4 توضیحات مکفی دادین امیدوارم که همینطور این تاپیک پر بار رو ادامه بدین .

موفق باشید ./

محسن شامحمدی
چهارشنبه 04 اسفند 1389, 20:25 عصر
دوست عزیز تمرینی که فرمودین رو حل کردم چقدر زود!!!
احسنت به شما.
البته کد شما توی سیستم من یک دفعه کار می کنه و دفعه بعد Exception می ده که دلیلش هم این خطه.

Dim a = bmp.Width - 1
Dim bb = (bmp.Width - 1) / 2توی این خط با این که به شی دسترسی اتفاق می افته ولی شما این خط ها رو قفل نکرده بودید.
بنده همچنان منتظر کار دوستانم.

Saman_12
چهارشنبه 04 اسفند 1389, 22:50 عصر
بفرما استاد اینم تمرین من!(آموزش توپی رو راه انداختی نکات جالبی رو بیان میکنه که حداقل من تاحالا نمی دونستم!).:تشویق:

توضیح 1) : اول یک Mutex به صورت عمومی تعریف کردم بعد هم توی هر دو تا Sub قبل از حلقه اول و بعد از پایانش اونو به ترتیب فعال و آزاد کردم.
توضیح 2) : اول یک Mutex به صورت عمومی تعریف کردم بعد هم هر جا که ترد ها به شی ای به صورت هم زمان دسترسی داشتند قبل از اون کد فعال بعد هم آزادش کردم.

hossein-khoshseyar
پنج شنبه 05 اسفند 1389, 08:22 صبح
سلام
ببخش که من وسط درس و پست های جالب شما یک پست می زنم
فقط خواستم تشکر کنم و بگم که من تقریبا 2 سالی هست که ار ترد تو برنامه هام استفاده می کنم . اما نکات خیلی زیادی رو از همین آموزش های شما یاد گرفتم که تاالان نمی دونستم
لطفا این تاپیک رو ادامه بدید به نظر من استقبال خوبی ازش میشه . شاید تا حالا کسی متوجهش نشده که آمار بازدید کنندش زیاد جالب نیست
اما آموزش خیلی خوب و کامل بود .
ممنون از اینکه به خواهش ما توجه کردید و چنین تاپیکی راه انداختید.

محسن شامحمدی
جمعه 06 اسفند 1389, 11:25 صبح
بفرما استاد اینم تمرین من!(آموزش توپی رو راه انداختی نکات جالبی رو بیان میکنه که حداقل من تاحالا نمی دونستم!).:تشویق:
اختیار دارین.شما خودت استاد مائی.


توضیح 1) : اول یک Mutex به صورت عمومی تعریف کردم بعد هم توی هر دو تا Sub قبل از حلقه اول و بعد از پایانش اونو به ترتیب فعال و آزاد کردم.آفرین به این پشتکار.
این یکی از لحاظ منطقی اشتباهه چرا؟چون اگر به خروجی دقت کنید می بینید که ابتدا یک ترد اجرا می شه بعدش ترد دیگه
چون اول تابع شما mutex رو در دست میگری و تا آخر رسم هم آزادش نمی کنی.به همین خاطر mutex وقتی آزاد می شه که کل یک تابع تمام شده باشه ولی هدف اصلی ما اینه که این دوتا بصورت همزمان رسم بشن.



توضیح 2) : اول یک Mutex به صورت عمومی تعریف کردم بعد هم هر جا که ترد ها به شی ای به صورت هم زمان دسترسی داشتند قبل از اون کد فعال بعد هم آزادش کردم. احسنت. این درسته.

پ.ن: برای حل این مسئله شما می تونید از هر شیئی که دوست دارید استفاه کنید که در پست 4 به طور مفصل توضیح داده شد.
و نکته آخر این که از توجه همتون ممنون.
به محض اینکه بتونم دوباره تاپیک رو ادامه می دم.شاید یک هفته دیگه.
الان دارم از توی کافی نت پست می دم.:خجالت:
هدف اصلی من بالابردن سطح دانش کاربران بخش وی بی دات و استفاده شما عزیزان از این غول بی شاخ و دم(Threading) هستش.
موفق و سربلند باشید
یک هفته دیگه می ریم سراغ :
درس بعدی: اجرای تایمر ولی در یک Thread دیگر!!!

محسن شامحمدی
پنج شنبه 12 اسفند 1389, 11:26 صبح
دوست عزیز یه سئوال
توی کد بالا شما نوشتی
Control.CheckForIllegalCrossThreadCalls = False



من که قبلا با ترد کار میکردم برای اینکه به اجزای بقیه ترد ها بتونم از توی ترد خودم تغییری ایجاد کنم و بهش دسترسی داشته باشم می نوشتم
CheckForIllegalCrossThreadCalls = False


الان توی کد شما هم که این خط رو جای کد شما کی زارم کار می کنه
می خواستم بپرسم می دونید که آیا اصلا این 2 تا با هم فرقی دارن یا نه؟
اگه دارن فرقش چیه؟
نه
هیچ فرقی نداره دوست عزیز.
مثل me.text و text که هیچ فرقی با هم ندارن.!

-------------------------------------------------------------------------------------------------------

دوست عزیز آیا این سه روشی که ذکز کردی هیچ فرقی با هم ندارن
با آزمایشات متعددی که من کردم Monitor بهترین نتیجه و Mutex بدترین نتیجه رو داره
یعنی با مانیتور دو تا ترد خیلی همزمان تر با هم تموم میشن ولی با موتکس تردها گاهن نسبت به هم فاصله زمانی پیدا می کنن
البته این نتیجه آزمایش بود از نظر عملکردی آیا فرقی بین این سه روش نیست ؟مطمئنا فرق که زیاد داره ولی من در مورد تفاوت هاش چیزی نمی دونم.
البته اگر واستون مهم باشه می تونید توی اینترنت چیزهای جالبی پیدا کنید.
نمونه
multithreading - Monitor vs Mutex in c# - Stack Overflow (http://stackoverflow.com/questions/1164038/monitor-vs-mutex-in-c)

When to use monitor, lock object, mutex and other syn. - .NET 247 (http://www.dotnet247.com/247reference/msgs/55/278544.aspx)

Difference between Monitor and Mutex (http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-clr/467/Difference-between-Monitor-and-Mutex)

Thread synchronization: Mutex or Monitor?? (http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/172652)

محسن شامحمدی
پنج شنبه 12 اسفند 1389, 12:14 عصر
درس بعدی: اجرای تایمر ولی در یک Thread دیگر!!!از قدیم گفتن مرده و قولش.

همگی شما مطمئنا با شی تایمر آشنایی دارید.
شی تایمر چیست؟
با این شی شما می تونید یک کد خاص را در یک بازه زمانی مشخص اجرا کنید مثلا هر 1000 میلی ثانیه (به عبارتی هر یک ثانیه) رنگ زمینه فرم عوض بشه.
خب یک تایمر می ذارید و INTERVAL اون رو روی 1000 تنظیم می کنید و کدهاتون رو توش می نویسید.
نکته:با استفاده از شی تایمر تمامی کدها در همان Thread اصلی برنامه اجرا می شود که این می تواند در بعضی موارد به شدت آزاردهنده باشد.مثلا در مواردی که شما مجبورید در داخل تایمر کدهای سنگینی اجرا کنید.
در این موارد بهتر است که شما از تایمری استفاده کنید که کدهای شما رو در یک Threadدیگه اجرا کنه.
و اینجاست که دات نت به شما راه حل ارائه میده.
System.Threading.Timer
که اینکار رو انجام می ده.
طریقه استفاده:


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
Dim t As New Threading.Timer(New Threading.TimerCallback(AddressOf work), Nothing, 0, 2000)
End Sub

Private Sub work()
'your codes here
End Sub

مزیت این کار:
سربار را از Thread اصلی برنامه بر می دارد که این دنیایی از مزیت است!!!:قهقهه:

http://icons.iconarchive.com/icons/umut-pulat/tulliana-2/128/k-timer-icon.png
نمونه نیز ضمیمه شده است.

درس بعدی: Thread Pooling

محسن شامحمدی
جمعه 13 اسفند 1389, 10:20 صبح
خب حالا نوبتی هم باشه می ریم سر بحث Thread Pool
این شی یکی از اشیا دات نت است که برنامه نویسی Multi Thread را بشدت ساده می کند.
تا بحال ما برای هر Thread ای که می خواستیم بسازیم یک شی از کلاس Threading.Thread تعریف می کردیم.
که این کار در مواردی که تعداد تردها زیاد باشد و ما نیاز خاصی به کنترل کامل آن تردها نداشته باشیم می توانیم به سادگی از این شی استفاده کنیم.
نام شی:
Threading.ThreadPool
http://www.codeproject.com/KB/threads/win32threadpool/threadpool.gif
توضیح :
ظرفی برای تردها-هر تردی که در این کلاس ذخیره شود به صف اجرای تردها می رود و اجرا می شود.
همچنین می توانیم برای تعداد تردهایی که بطور همزمان در این ظرف اجرا می شوند محدودیت ایجاد کنیم.
نحوه استفاده:
imports system.threading
------------------------
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf MethodeName), Nothing)

درس بعدی:کلاس Interlocked

محسن شامحمدی
شنبه 14 اسفند 1389, 18:46 عصر
از این کلاس برای جلوگیری از مشکلاتی که می تواند هنگام عملیات ریاضی چندین ترد به صورت همزمان اجرا شود،استفاده کرد.
این کلاس از متدهای Increment,decrement,exchange,compare پشتیبانی می کند.
مثال:
Sub ThreadA(ByRef IntA As Integer)
System.Threading.Interlocked.Increment(IntA)
End Sub
Sub ThreadB(ByRef IntA As Integer)
System.Threading.Interlocked.Increment(IntA)
End Sub
درس بعدی: ارسال پارامتر به متد اجراشونده با Thread

محسن شامحمدی
یک شنبه 15 اسفند 1389, 08:46 صبح
در بسیاری از اوقات متدی که توسط ترد ما اجرا می شود دارای پارامتر نیز هست.
در این موارد می توانیم به صورت زیر پارامتر خود را به متدی که توسط ترد اجرا می شود پاس بدهیم.


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim t As New Threading.Thread(AddressOf work)

t.Start("my parameter")

End Sub



Private Sub work(ByVal arg As String)

MsgBox(arg)

End Sub

محسن شامحمدی
دوشنبه 16 اسفند 1389, 17:20 عصر
ارزش همزمان سازی تردها در برنامه های multi thread بر هیچ کسی پوشیده نیست.اما در بعضی موارد که چند Thread منتظر همدیگر هستند خطر بن بست وجود دارد.
برای مثال فرض کنید در یک چهارراه چند ماشین ایستاده اند و منتظرند که شخص دیگری حرکت کند.در وضعیت بن بست همه چیز به حالت خلسه می رود.پس احتیاجی به گفتن نیست که اجتناب از بن بست خیلی مهم است.راه های زیادی برای رفتن به بن بست وجود دارد و البته راه های بسیار زیادی برای اجتناب از بن بست وجود دارد.
البته بحث بن بست ها بحث گسترده ای است که در بحث ما نمی گنجد ولی نکته کلیدی ای که در این بحث وجود دارد این است که اگر شما قبل از کدنویسی نحوه اجرای تردها و اعمال هر کدام را رسم و بررسی کنید در اکثر موارد دچار چنین مشکلاتی نخواهید شد.
منبع: ترجمه ای از مقاله Multithreaded Programming with Visual Basic .NET


فعلا هم درس تمام شد تا ببینم چیز دیگه ای اگر واسه گفتن هست بگم/استقبال به شدت کم بود/منتظر سوالات شما عزیزان هستم/در مورد این دو مبحث تحقیق می کنم تا اگر یاد گرفتم به شما هم یاد بدم
در پایان از جناب مجتبی تاجیک (http://www.google.com/url?sa=t&source=web&cd=1&ved=0CBQQFjAA&url=http%3A%2F%2Fbarnamenevis.org%2Fmember.php%3F6 3881-%25D9%2585%25D8%25AC%25D8%25AA%25D8%25A8%25DB%258C-%25D8%25AA%25D8%25A7%25D8%25AC%25DB%258C%25DA%25A9&ei=hRN7TeDiGIb6sgbit6HwBw&usg=AFQjCNEfmGM39IwyHySUlrSDPvuvEMMeFg) به خاطر آموزش هایی که بدون هیچ چشم داشتی به بنده دادند صمیمانه تشکر می کنم.

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


و در کل الان از اینکه این تاپیک آموزشی رو زدم پشیمونم:افسرده:
باور کنید اکر یک تاپیک می زدم که توش جوک و Sms می ذاشتم الان بالای 3000 تا بیننده و تشکرداشت!!!

HackersKing
جمعه 19 فروردین 1390, 10:31 صبح
و در کل الان از اینکه این تاپیک آموزشی رو زدم پشیمونم:افسرده:
باور کنید اکر یک تاپیک می زدم که توش جوک و Sms می ذاشتم الان بالای 3000 تا بیننده و تشکرداشت!!!


محسن جان عزیز شاید بچه ها کم لطفی کردن اما من که از این تاپیک خیلی لذت بردم .

آموزش کاملی بود.

FastCode
یک شنبه 04 اردیبهشت 1390, 09:21 صبح
اگر میخوای لینوکسی ها هم بیان اینجا و بحث داغ بشه(دعوا/اشپیلن) fork رو هم بیار توی بحث و مقایسه کن.
اول با یک مقایسه متنی شروع کن.سعی میکنم هر مبحثی رو که توضیح میدی کدش رو بزارم.

This_is_ALireza
سه شنبه 15 آذر 1390, 11:12 صبح
اقا من یه مشکل اساسی دارم
دیروز از VB6 به DotNet مهاجرت کردم
یه دلیل اینکه دیگه خواسته های منو نمی تونست بر آورده کنه
مثل همین Threading ، Messaging , وراثت . ...
حالا من سریع اومدم تو کار همین چیزایی که VB6 نداشت
چون حوصله مباحث ابتدایی رو ندارم

یه برنامه خیلی ساده نوشتم ( واسه تست)
اما کار نمی کنه
یه ماژول درست کردم توش یه ساب نوشتم که یه حلقه بی نهایته و مقدار TEXTBox رو (که تو فرم هست) هر دفعه 1 واحد زیاد می کنه
وقتی این ساب رو از تو فرم با یک دکمه اجراش می کنم هیچ مشکلی نیست
اما وقتی همین کار رو با Thread انجام می دم همه ی قسمت ها کار می کنه ( Trace کردم ) اما همین خطی که قراره مقدار TEXTBOX رو تغییر بده کار نمی کنه
Error هم نمی ده

چه مشکلی داره؟
این مشکلات کوچیک و بی خود آدمو عصبی می کنه

Public Sub MyCounter1()
Dim cnt As Integer

Do
cnt = cnt + 1

Application.DoEvents()

Form1.TextBox1.Text = Form1.TextBox1.Text = cnt.ToString

Loop

ali190
سه شنبه 15 آذر 1390, 12:58 عصر
باسلام و عرض خسته نباشید
دوستان بنده به تازگی با مفهوم Thread آشنا شدم
هنوز نمیدونم که مفهومش رو درست درک کرده ام یا نه
شناختم از thread رو با ذکر مثالی توضیح میدم ، شما بمن بگید که درست متوجه شدم یا نه؟
فرض کنید من در برنامه ام فرمی دارم که که در این فرم یک گرید ویو وجود داره که آدرس یک سری فایل درش ذخیره شده
در این فرم کاربر میتونه این عملیات رو انجام بده:
1- در گریدویو میتونه عملیات سرچ رو انجام بده
2- به لیست موجود میتونه فایل جدیدی رو اضافه کنه
3-میتونه با کلیک بر روی یک فایل عملیات کپی (تهیه نسخه کپی از اون فایل) در یک مسیر دلخواه رو انجام بده
طبیعتاً سنگین ترین کار از بین این سه عملیات ، کپی ردن فایل هست که اگر حجم فایل انتخابی زیاد باشه امکانش هست که فرم برنامه قفل کنه و ما نتونیم در هنگام کپی مثلاً‌عملیات جستجو رو انجام بدیم
برای اینکه از این مشکل راحت بشیم در ساده ترنی حالت میاییم و هر عملیات رو در یک Thread تعریف میکنیم و به اصطلاح عامیانه انجام هر کدام از اونهارو مستقل از هم میکنیم
اینطوری هنگام انجام یک عملیات ، عملیات دیگر هم میتونن به طور موازی انجام بشن
اگر برداشتم از Thread درست هست بمن بگید
خیلی خیلی ممنون
یاعلی

This_is_ALireza
سه شنبه 15 آذر 1390, 13:03 عصر
بله همینطوره

This_is_ALireza
سه شنبه 15 آذر 1390, 13:04 عصر
اقا من یه مشکل اساسی دارم
دیروز از VB6 به DotNet مهاجرت کردم
یه دلیل اینکه دیگه خواسته های منو نمی تونست بر آورده کنه
مثل همین Threading ، Messaging , وراثت . ...
حالا من سریع اومدم تو کار همین چیزایی که VB6 نداشت
چون حوصله مباحث ابتدایی رو ندارم

یه برنامه خیلی ساده نوشتم ( واسه تست)
اما کار نمی کنه
یه ماژول درست کردم توش یه ساب نوشتم که یه حلقه بی نهایته و مقدار TEXTBox رو (که تو فرم هست) هر دفعه 1 واحد زیاد می کنه
وقتی این ساب رو از تو فرم با یک دکمه اجراش می کنم هیچ مشکلی نیست
اما وقتی همین کار رو با Thread انجام می دم همه ی قسمت ها کار می کنه ( Trace کردم ) اما همین خطی که قراره مقدار TEXTBOX رو تغییر بده کار نمی کنه
Error هم نمی ده

چه مشکلی داره؟
این مشکلات کوچیک و بی خود آدمو عصبی می کنه

Public Sub MyCounter1()
Dim cnt As Integer

Do
cnt = cnt + 1

Application.DoEvents()

Form1.TextBox1.Text = Form1.TextBox1.Text = cnt.ToString

Loop



حالا اینو یکی حل کنه

vb.net.33
پنج شنبه 24 آذر 1390, 14:47 عصر
سلام خسته نباشید و مطالب عالی بودند.

من به تازگی برام یه مشکل در رابطه نخها پیش امده. و سوالم رو تو لینک زیر گذاشتم:

لینک (http://barnamenevis.org/showthread.php?318198-%D8%B9%D8%AF%D9%85-%D8%A7%D8%AC%D8%B1%D8%A7%DB%8C-Thread-%D9%87%D9%86%DA%AF%D8%A7%D9%85-%D9%81%D8%B1%D8%A7%D8%AE%D9%88%D8%A7%D9%86%DB%8C-%D8%B3%D8%A7%D8%A8-%D8%A7%D8%B2-%D9%85%D8%A7%DA%98%D9%88%D9%84%21%21%21)

مرتضی تقدمی
چهارشنبه 03 اسفند 1390, 21:39 عصر
اقا من یه مشکل اساسی دارم
دیروز از VB6 به DotNet مهاجرت کردم
یه دلیل اینکه دیگه خواسته های منو نمی تونست بر آورده کنه
مثل همین Threading ، Messaging , وراثت . ...
حالا من سریع اومدم تو کار همین چیزایی که VB6 نداشت
چون حوصله مباحث ابتدایی رو ندارم

یه برنامه خیلی ساده نوشتم ( واسه تست)
اما کار نمی کنه
یه ماژول درست کردم توش یه ساب نوشتم که یه حلقه بی نهایته و مقدار TEXTBox رو (که تو فرم هست) هر دفعه 1 واحد زیاد می کنه
وقتی این ساب رو از تو فرم با یک دکمه اجراش می کنم هیچ مشکلی نیست
اما وقتی همین کار رو با Thread انجام می دم همه ی قسمت ها کار می کنه ( Trace کردم ) اما همین خطی که قراره مقدار TEXTBOX رو تغییر بده کار نمی کنه
Error هم نمی ده

چه مشکلی داره؟
این مشکلات کوچیک و بی خود آدمو عصبی می کنه

Public Sub MyCounter1()
Dim cnt As Integer

Do
cnt = cnt + 1

Application.DoEvents()

Form1.TextBox1.Text = Form1.TextBox1.Text = cnt.ToString

Loop



سلام
کد زیر را به ابتدای کدها اضافه کنید:


CheckForIllegalCrossThreadCalls = False

موفق باشید

zaeimh90
یک شنبه 29 مرداد 1391, 19:11 عصر
سلام خدمت همه بزرگان.
به یه مشکل جاب تو زمینه چند نخی ها خوردم.میدونید که با دستور CheckForIllegalCrossThreadCalls = False میونیم به آبجکتهای فرم هم دست رسی داشته باشیم.ولی جالبه نمیتونیم داخله یه ترد به خصوصیت enable یک تایمر دسترسی داشته باشیم!!!:متعجب:
اگه کسی بتونه کمک کنه ممنون میشم.
راستی جا داره از آقا محسن برای ایجاد این تاپیک تشکر کنم.

محسن شامحمدی
سه شنبه 31 مرداد 1391, 19:08 عصر
سلام خدمت همه بزرگان.
به یه مشکل جاب تو زمینه چند نخی ها خوردم.میدونید که با دستور CheckForIllegalCrossThreadCalls = False میونیم به آبجکتهای فرم هم دست رسی داشته باشیم.ولی جالبه نمیتونیم داخله یه ترد به خصوصیت enable یک تایمر دسترسی داشته باشیم!!!:متعجب:
اگه کسی بتونه کمک کنه ممنون میشم.
راستی جا داره از آقا محسن برای ایجاد این تاپیک تشکر کنم.

اصولیش اینه که از کلاس تایمر (http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx) استفاده کنید.ولی اگر اصرار دارید که همین کد رو ترمیم کنید از کد زیر استفاده کنید:
if (this.InvokeRequired)
{
BeginInvoke(new MyDelegate(delegate()
{
timer.Enabled = true;
}));
}


منبع: Stackoverflow
بابت کد معذرت می خوام که سی شارپه!

zaeimh90
چهارشنبه 01 شهریور 1391, 01:59 صبح
ممنون.
خوب میشه یه آموزشم در مورد این invoke بذاری.واقعا ممنون میشم.
هم اینکه این invoke چیه و هم delegate.
کار میکنه ولی نمیفهمم چیه.ممنون میشم.:ناراحت:

ali reza mansoori 2
یک شنبه 05 شهریور 1391, 23:19 عصر
دوست عزیز آموزش خوبی هستش
لطفا ادامه بدید
من با همین روشی که شما گفتید یه SUB رو فراخوانی کردم که یه عمل سنگینی رو انجام میده مشکلی نداره
فقط میخوام در حال انجام این کار یه پروسس بار رو هم مقدار دهی کنم
اگر امکان داره راهنمایی کنید لطفا

Hossein742
دوشنبه 11 آذر 1392, 22:18 عصر
سلام
اگه میشه برنامه زیر رو برای من بنویسید ،،،
با استفاده از multi threading یک رشته از عملیات محاسباتی دریافت شده از کاربر را حل و جواب نهایی را بدهد
مثلا در رشته عملیات زیر
a×b+c/f+g
هر ترد کار یک عمل ریاضی را انجام دهد
ویک تابع بر اساس اولویت های عملگر ها ، ترد ها رو زمانبندی کنه ،،،
مثلا اولا ترد ضرب اجرا بشه بعد ترد تقسیم سپس حاصل دو ترد قبلی در ترد جمع اول محاسبه و جواب را برای جمع در ترد جمع بعدی بفرستد و نتیجه در اخر نمایش داده شود

zfarzah
یک شنبه 15 تیر 1393, 00:15 صبح
ممنون از آموزش جامعتون

ehsan-68
سه شنبه 15 اردیبهشت 1394, 08:32 صبح
[QUOTE=محسن شامحمدی;1223080]از قدیم گفتن مرده و قولش.

همگی شما مطمئنا با شی تایمر آشنایی دارید.
شی تایمر چیست؟
با این شی شما می تونید یک کد خاص را در یک بازه زمانی مشخص اجرا کنید مثلا هر 1000 میلی ثانیه (به عبارتی هر یک ثانیه) رنگ زمینه فرم عوض بشه.
خب یک تایمر می ذارید و INTERVAL اون رو روی 1000 تنظیم می کنید و کدهاتون رو توش می نویسید.
نکته:با استفاده از شی تایمر تمامی کدها در همان Thread اصلی برنامه اجرا می شود که این می تواند در بعضی موارد به شدت آزاردهنده باشد.مثلا در مواردی که شما مجبورید در داخل تایمر کدهای سنگینی اجرا کنید.
در این موارد بهتر است که شما از تایمری استفاده کنید که کدهای شما رو در یک Threadدیگه اجرا کنه.
و اینجاست که دات نت به شما راه حل ارائه میده.
System.Threading.Timer
که اینکار رو انجام می ده.
طریقه استفاده:


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
Dim t As New Threading.Timer(New Threading.TimerCallback(AddressOf work), Nothing, 0, 2000)
End Sub

Private Sub work()
'your codes here
End Sub

مزیت این کار:
سربار را از Thread اصلی برنامه بر می دارد که این دنیایی از مزیت است!!!:قهقهه:
---------------------------------
سلام ...

ممنون بابت این تایپیک ...

ممکنه قدیمی باشه ...

ولی خیلی دنبالش بودم ...

و 1 ؟

خب الان این تایمرو چطور استاپ کنم ؟؟؟؟؟؟؟؟؟؟

javadmoorf
چهارشنبه 23 اردیبهشت 1394, 09:39 صبح
ممنون از پستتون.

mmbguide
دوشنبه 21 فروردین 1396, 15:20 عصر
چه طور ميتوان از ترد ها براي خواندن اطلاعات از ديتابيس استفاده کرد تا برنامه به مشکل بر نخوره و کند نشه
نحوه دسترسی صحیح انتقال اطلاعات بین تردها




باتشکر از جناب شامحمدی بخاطر مطالب ارزشمند ایشان.

اگر لطف بفرمایید در خصوص استفاده از Threadها در برنامه های داده محور که باید با بانک های اطلاعاتی ارتباط داشته باشند مطلب رو ادامه بدید بسیار ممنون خواهم بود. چون سوال در همین خصوص داشتم و بخاطر اینکه نخواستم موضوع پراکنده بشه تاپیک ایجاد نکردم.

تشکر

mmbguide
یک شنبه 27 فروردین 1396, 19:34 عصر
سلام

من یک Thread.Timer ایجاد کردم در صفحه اصلی که یک روال معمولی که کارش اضافه کردن یک واحد به یک متغیر هستش و مقدار اون در هر Interval در صفحه و در یک label نمایش داده میشه. حالا اگر من یک فرم دیگر را ShowDilaog کنم Timer عدد رو جمع نمیکنه. مشکل از کجاست. البته اگر از یک شیء Timer از ToolBox اضافه کنم این مشکل وجود نداره. لطفا راهنمایی کنید.

تشکر

mmbguide
دوشنبه 04 اردیبهشت 1396, 23:46 عصر
جواب رو از لینک زیر پیدا کردم. ابتدا باید متغیر Timer بصورت Private تعریف بشه.

http://stackoverflow.com/questions/2196825/why-does-system-threading-timer-stop-on-its-own

mmbguide
دوشنبه 04 اردیبهشت 1396, 23:50 عصر
سوال خیلی مهمی که داشتم اینه که چرا اکثر برنامه نویسان میگن نباید از CheckForIllegalCrossThreadCalls = False استفاده کرد؟ علت چیه و برای تعامل با اشیاء روی فرم باید چکار کرد. البته من سعی میکنم متغیر ها رو مقداردهی کنم و یک تایمر از ToolBox هم اضافه میکنم که در Interval مشخص مقادیر متغیرها رو بخونه و در اشیاء روی فرم نمایش بده. آیا نمیشه از همون Thread بطوری که از CheckForIllegalCrossThreadCalls = False استفاده نشه با اشیاء روی فرم ارتباط برقرار کرد؟

تشکر