PDA

View Full Version : چرا داخل یک Thread نمیتوان خصوصیات یک کنترل را تغییر داد؟؟؟



shahryari
یک شنبه 22 اردیبهشت 1392, 18:42 عصر
باسلام
با توجه به نمونه کدهای زیر لطفا راهنمایی کنید (البته کدها منباب مثال است)
Dim t As Thread
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
t = New Thread(AddressOf test)
t.Start()

End Sub


Sub test()
Label1.Text = "Test.."
End Sub

با تشکر

pooya1072
یک شنبه 22 اردیبهشت 1392, 19:37 عصر
سلام
دوست عزیز ... وقتی شما یه پروژه جدید رو ایجاد می کنید به صورت پیش فرض این برنامه تحت یک thread اصلی اجرا میشه . تمام متعلقات فرم اصلی برنامه توسط این thread کنترل میشه . شما نمی تونید از طریق یه thread دیگه به متعلقات یه thread دیگه دسترسی پیدا کنید . حالا برای حلش می تونید از متغیر های عمومی استفاده کنید . مثلا برای مثال بالا در تابع Test به جای مقدار دادن به لیبل به یک متغیر واسطه مقدار دهی کنید و در ادامه برنامه اون متغیر رو توی لیبل بریزید.

FastCode
یک شنبه 22 اردیبهشت 1392, 19:45 عصر
از Invoke استفاده کنید.
حست و جو کنید Control.Invoke

مهرداد صفا
دوشنبه 23 اردیبهشت 1392, 01:01 صبح
با سلام.
به طور پیشفرض برای جلوگیری از نتایج غیر قابل پیشبینی ناشی از دسترسی همزمان چند thread به یک کنترل، کنترلها فقط از طریق thread سازندهشان قابل تغییر هستند. برای اینکه بتوانید از thread های دیگر به کنترلها دسترسی داشته باشید خصوصیت Control.CheckForIllegalCrossThreadCalls را به مقدار false تغییر دهید. مثال:


'in the name of god
'صل الله علی محمد و آله

Public Class Form1
Dim Thread2 As New Threading.Thread(AddressOf test)

Sub test()
Me.Text = "ok"

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread2.Start()
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Control.CheckForIllegalCrossThreadCalls = False
End Sub
End Class


راه دیگر همانطور که جناب fastcode اشاره کردند اجرای کد مربوط به تغییر خصوصیات کنترل، از طریق thread سازنده کنترل است. در واقع با متود Control.Invoke ما delegate مورد نظر را از طریق thread سازنده کنترل که معمولا همان thread اصلی برنامه است اجرا می کنیم. مثال:



'in the name of god
'صل الله علی محمد و آله

Public Class Form1
Dim Thread2 As New Threading.Thread(AddressOf test)

Sub test()
Me.Invoke(Sub() Me.Text = "ok")

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread2.Start()
End Sub


End Class

shahryari
دوشنبه 23 اردیبهشت 1392, 16:40 عصر
با سلام و تشگر
بهترین جواب تاپیک

با سلام.
به طور پیشفرض برای جلوگیری از نتایج غیر قابل پیشبینی ناشی از دسترسی همزمان چند thread به یک کنترل، کنترلها فقط از طریق thread سازندهشان قابل تغییر هستند. برای اینکه بتوانید از thread های دیگر به کنترلها دسترسی داشته باشید خصوصیت Control.CheckForIllegalCrossThreadCalls را به مقدار false تغییر دهید. مثال:


'in the name of god
'صل الله علی محمد و آله

Public Class Form1
Dim Thread2 As New Threading.Thread(AddressOf test)

Sub test()
Me.Text = "ok"

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread2.Start()
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Control.CheckForIllegalCrossThreadCalls = False
End Sub
End Class


راه دیگر همانطور که جناب fastcode اشاره کردند اجرای کد مربوط به تغییر خصوصیات کنترل، از طریق thread سازنده کنترل است. در واقع با متود Control.Invoke ما delegate مورد نظر را از طریق thread سازنده کنترل که معمولا همان thread اصلی برنامه است اجرا می کنیم. مثال:



'in the name of god
'صل الله علی محمد و آله

Public Class Form1
Dim Thread2 As New Threading.Thread(AddressOf test)

Sub test()
Me.Invoke(Sub() Me.Text = "ok")

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Thread2.Start()
End Sub


End Class

FastCode
دوشنبه 23 اردیبهشت 1392, 18:36 عصر
با سلام و تشگر
بهترین جواب تاپیک
کار کردنش دلیل نمیشه بهترین جواب باشه.
اتفاقا جواب خیلی بدیه که مایکروسافت مجبور شد در نسخه های اولیه دات نت بخاطر اشتباهی که در طراحیشون انجام داده بودن اضافه کنه و ممکنه هر لحظه از دات نت حذف بشه.