PDA

View Full Version : در ارتباط با تردها



peymannaji
سه شنبه 06 اسفند 1387, 01:53 صبح
با سلام
من یک تابع دارم که ابتدای تابع دکمه ای disable و آخر تابع بعد از اجرا شدن تمام موارد enable میشه . این تابع تا زمانی که که در یک ترد ننداختم و مستقیم اجرا میشه مشکلی نداره اما به محض start بوسیله ترد ارور زیر رو میده دوستان محبت فرمایند راهنمایی کنند .



Cross-thread operation not valid: Control 'Button3' accessed from a thread other than the thread it was created on.
Button3 همان دکمه ای هست که عمل disable و enable روش انجام شد ...

با تشکر

Microsoft.net
سه شنبه 06 اسفند 1387, 11:27 صبح
خیلی واضحه که مشکلت چیه ! اشتباهت اینه که از یک Thread داری در یک Thread دیگه دستکاری انجام میدی و این مجاز نیست دلیلشم بوجود اومدن Race Condition و مشکلات همروندی نخ ها ست که کامپایلر اونو محدود کرده .
راه حلت اینه که از BackGroundWorkder استفاده کنی و توی رویداد ReportProgress کدتو بنویسی.
مثالهاش تو MSDN هست

Ali_Mor
سه شنبه 06 اسفند 1387, 11:30 صبح
از داخل یک ترد نمی تونی به شی ای که در یک ترد دیگه ساخته شده دسترسی داشته باشی. Button3 در ترد فرم ساخته شده است و از ترد دیگر قابل دسترسی بصورت معمول نیست. اجمالا بگم که باید از Delegate استفاده کنی. در MSDN مثال هائی برای این منظور آورده شده است.
این رو ببین
http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx (http://msdn.microsoft.com/en-us/library/ms171728%28VS.80%29.aspx)

peymannaji
سه شنبه 06 اسفند 1387, 23:04 عصر
خیلی واضحه که مشکلت چیه ! اشتباهت اینه که از یک Thread داری در یک Thread دیگه دستکاری انجام میدی و این مجاز نیست دلیلشم بوجود اومدن Race Condition و مشکلات همروندی نخ ها ست که کامپایلر اونو محدود کرده .
راه حلت اینه که از BackGroundWorkder استفاده کنی و توی رویداد ReportProgress کدتو بنویسی.
مثالهاش تو MSDN هست


سلام دوست عزیز این رویداد ReportProgress در کامپوننت BackGroundWorkder رو پیدا نکردم . راهنمایی میفرمائید ؟

peymannaji
سه شنبه 06 اسفند 1387, 23:07 عصر
از داخل یک ترد نمی تونی به شی ای که در یک ترد دیگه ساخته شده دسترسی داشته باشی. Button3 در ترد فرم ساخته شده است و از ترد دیگر قابل دسترسی بصورت معمول نیست. اجمالا بگم که باید از Delegate استفاده کنی. در MSDN مثال هائی برای این منظور آورده شده است.
این رو ببین
http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx (http://msdn.microsoft.com/en-us/library/ms171728%28VS.80%29.aspx)


والا اونجا کلی کد بود من اصلا نفمیدم چیکار باید کرد راهنمایی می فرمائید ؟

Ali_Mor
چهارشنبه 07 اسفند 1387, 00:13 صبح
باید یک تابع تعریف کنی که در آنجا عملیات Desable/Enableروی باتن رو انجام بدی. بعد یک Delegate داشته باشی که به این تابع اشاره کنه. در ترد بجای تغییر مستقیم باتن این تابع رو فراخوانی کن


Delegate Sub SetEnableCallBack(ByVal bEnable As Boolean)

Private Sub SetEnable(ByVal bEnable As Boolean)

If Me.Button3.InvokeRequired Then
Dim d As New SetEnableCallBack(AddressOf SetEnable)
Me.Invoke(d, New Object() {bEnable})
Else
Me.Button3.Enabled = bEnable
End If
End Sub
حرف دوستمون هم درسته. رویداد RunWorkerCompleted هنگام اتمام کار ترد کنترل BackGroundWorkder رخ میدهد(از این می توانی برای Enableکردن باتن استفاده نمائی).

peymannaji
جمعه 09 اسفند 1387, 02:17 صبح
ممنون علی جان از راهنماییتون ... با background worker کار خیلی راحتر انجام میشه . اما سرعت آن نسبت به Thread کمی پایین هست البته صحبت سر 1-2 ثانیه هست ... اما روش شما رو هم امتحان میکنم چون بیشتر مد نظر بنده هست ...

موفق باشید .