PDA

View Full Version : گفتگو: چرا وقتی یه عملیات بزرگ پردازش میکنیم فرم هنگ میکنه و راه حلش چیه



hamed.alinejad
چهارشنبه 18 مرداد 1391, 20:25 عصر
سلام دوستان عزیز من تا به الان تو این سایت هر سوالی پرسیدم کسی جواب نداده حداقل اینو کمکم کنید

من یه فرو دارم و یه progressbar و یک دکمه
توی دکمه یه عملیات مربوط به شبکه نوشتم خودتون هم میدونید چون میخواد وصل بشه به شبکه چند لحظه فرم هنگ میکنه تا وصل بشه و حتی خود progress تو این لحظه هنگ میکنه

من چطوری میتونم کاری کنم که حداقل در حین این عملیات progressbar کار کنه و اونطوری کاملا هنگ نکنه ؟؟؟

amirzandi
چهارشنبه 18 مرداد 1391, 20:28 عصر
باید از Thread ها استفاده کنین... سرچ کنین یه چیزایی می بینین... اگه خواستین بگین من نمونه بزارم.

hamed.alinejad
چهارشنبه 18 مرداد 1391, 20:55 عصر
ممنون میشم اگه یه نمونه بزارید توی vb2010 هست پروژه من

amirzandi
چهارشنبه 18 مرداد 1391, 21:10 عصر
Public Class Form1
Private Sub Ping()
If Me.Label1.InvokeRequired Then
If My.Computer.Network.IsAvailable Then
Invoke(New _PingDelegate(AddressOf PingAction), New Object() {My.Computer.Network.Ping("4.2.2.3").ToString})
Else
Me.Label1.Text = "کارت شبکه فعال نیست"
End If
End If
End Sub
Private Sub PingAction(ByVal message As Object)
Me.Label1.Text = message
End Sub
Private Delegate Sub _PingDelegate(ByVal message As Object)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Label1.Text = "Ping in progress..."
Dim t As New Threading.Thread(AddressOf Ping)
t.IsBackground = True
t.Start()
End Sub

End Class

hamed.alinejad
چهارشنبه 18 مرداد 1391, 21:20 عصر
داداش خیلی خیلی ممنون بابت کد


داداش من یه سوال تو یه تاپیک دیگه داشتم میتونی به اونم جواب بدی فکر میکنم خیلی واردی اونم بتونی کمکم کنید
http://barnamenevis.org/showthread.php?355306-%D8%A7%D9%86%D8%AA%D9%82%D8%A7%D9%84-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA-%D8%A7%D8%B2-%DA%A9%D9%84%D8%A7%DB%8C%D9%86%D8%AA-%D8%A8%D9%87-%D8%B3%D8%B1%D9%88%D8%B1-%D8%AF%D8%B1-sql-%D9%88-vb.net&p=1566245#post1566245

armin001
چهارشنبه 18 مرداد 1391, 21:21 عصر
یه کم سرچ میکردی به یه چیزایی میرسیدی چون قبلا خودم این سوالو کردم به این لینک برو مشکلت حل میشه مشکل من که حل شد

http://barnamenevis.org/showthread.php?351236-%D9%87%D8%B1-%DA%A9%D8%A7%D8%B1%DB%8C-%DA%A9%D9%87-%D9%85%DB%8C-%DA%A9%D9%86%D9%85-%D8%B2%D9%85%D8%A7%D9%86-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%DA%A9%D8%B1%D8%AF%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%87%D8%A7%D9%85-%D9%87%DB%8C%DA%86-%DA%A9%D8%A7%D8%B1%DB%8C-%D8%B1%D9%88%DB%8C-%D9%81%D8%B1%D9%85-%D9%86%D9%85%DB%8C%D8%AA%D9%88%D9%86%D9%85-%D8%A7%D9%86%D8%AC%D8%A7%D9%85-%D8%A8%D8%AF%D9%85

hamed.alinejad
چهارشنبه 18 مرداد 1391, 21:54 عصر
فقط یه مشکل کوچیک دارم
من این کد رو نوشتم و میخوام وقتی اینو زدن دکمه غیر فعال بشه و وقتی عملیات تموم شد دکمه بازم فعال بشه اما این خطا رو داد و از دستور زیر استفاده کردم یه کمکی به این بکنید

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

Public Class receive_info_from_server1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Button1.Enabled = False
Dim t As New Threading.Thread(AddressOf test)
t.Start()


End Sub
Public Sub test()

netcon.Open()
Button1.Enabled = True

End Sub

Sub hamed()
Button1.Enabled = True
End Sub

End Class



و این خطا رو میده برای فعال کردن دکمه

Cross-thread operation not valid: Control 'Button1' accessed from a thread other than the thread it was created on.

hamed.alinejad
پنج شنبه 19 مرداد 1391, 00:58 صبح
تو رو خدا کمکم کنید من چطوری الان به اجزا دستری پیدا کنم. این خطا رو چطوووور حل کنم واجبه برام خیلی افتضاح

Saman_12
پنج شنبه 19 مرداد 1391, 01:35 صبح
تو رو خدا کمکم کنید من چطوری الان به اجزا دستری پیدا کنم. این خطا رو چطوووور حل کنم واجبه برام خیلی افتضاح
جستجو کنی خیلی زود تر به جاب میرسی واسه کم کردن شر این خطا د راه داری 1 اصولی 2 غیر اصولی :
1.invoke کردن (همین رو سرچ کنی کلی مطلبه) :

Private Delegate Sub WriteToConsoleDelegate(conRT As Object, text As String)
Private Sub WriteToConsole(conRT As Object, Optional text As String = "")

If Me.InvokeRequired Then

Me.Invoke(New WriteToConsoleDelegate(AddressOf WriteToConsole), conRT, text)
Else

conRT.AppendText(text & vbNewLine)
Console.WriteLine(text)
End If
End Sub

2. :

Control.CheckForIllegalCrossThreadCalls = False

the king
پنج شنبه 19 مرداد 1391, 01:41 صبح
باید خطا بده، چون Thread جدیدی که ساخته اید که نمی تونه به Button1 که تحت کنترل Thread اصلی دستوری بده، باید با
Invoke کردن از Thread اصلی خواهش کنید که دکمه رو براتون فعال کنه :

Private Delegate Sub EnableButton()

Private Sub EnableButton1()
Button1.Enabled = True
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Button1.Enabled = False
Dim t As New Threading.Thread(AddressOf test)
t.Start()
End Sub

Public Sub test()
netcon.Open()
Invoke(New EnableButton(AddressOf EnableButton1))
End Sub

amirzandi
پنج شنبه 19 مرداد 1391, 07:15 صبح
همانطور که سامان عزیز اشاره کردند ، راه دوم اصلا اصولی نیست و پیشنهاد نمی شه... این کد را برات می زارم به قسمت DoneAction توجه کن:

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Label1.Text = "Ping in progress..."
Me.Button1.Enabled = False
Dim t As New Threading.Thread(AddressOf Action)
t.IsBackground = True
t.Start()
End Sub
#Region "Action"
Private Delegate Sub _ActionDelegate(ByVal msg As Object)
Private Sub Action()
If Me.Button1.InvokeRequired Then
Invoke(New _ActionDelegate(AddressOf ActionDelegate), New Object() {My.Computer.Network.Ping("4.2.2.4").ToString})
Invoke(New _DoneActionDelegate(AddressOf DoneAction))
End If
End Sub
Private Sub ActionDelegate(ByVal msg As Object)
Me.Label1.Text = msg.ToString
End Sub
#End Region
#Region "Done Action"
Private Delegate Sub _DoneActionDelegate()
Private Sub DoneAction()
Me.Button1.Enabled = True
End Sub
#End Region
End Class

tooraj_azizi_1035
شنبه 21 مرداد 1391, 20:13 عصر
باید برنامه نویسی Async انجام بدی. پک رو دانلود کن و بعد کلمه کلیدی async رو خیلی راحت به متدت اضافه کن بقیه کار رو خودش انجام میده! http://www.microsoft.com/en-us/download/details.aspx?id=9983
فیلم: http://msdn.microsoft.com/en-us/vstudio/hh378091

لینک دیگر: http://msdn.microsoft.com/en-us/library/aa289178%28v=vs.71%29.aspx

SALMOON
شنبه 21 مرداد 1391, 21:25 عصر
باید از BACKGROUND WORKER استفاده کنی

amirzandi
شنبه 21 مرداد 1391, 21:30 عصر
Salmoon عزیز این کدی که دادم فکر نکنم فرقی با background worker داشته باشه...

zaeimh90
یک شنبه 22 مرداد 1391, 01:08 صبح
یه پیشنهاد ساده تر میدم.
داخل وبی یه امکان هست که خیلی عالیه اونم doevents هست.
که اگر اونو داخل یک for بزاری یا هرچیزی که کمی طول میکشه دیگه برنامه هنگ نمیکنه باعث میشه که تمام قسمتها اول انجام بشه وقتی که انجام شد بعد میره متغییر for رو اضافه میکنه.کارش مثله thread میمونه.
امتحان کن.من که کارک با این حل شده.
اینوجوری بزار اول for : البته فرقی نمیکنه کجاش application.doevents

amirzandi
یک شنبه 22 مرداد 1391, 08:04 صبح
Application.DoEvents اصلا راه منطقی نیست ، خیلی وقت ها باعث می شه برنامه شما Hang کنه.... من نمی دونم یعنی استفاده از Thread ها اینقدر سخت هست؟ به خدا با 2-3 تا تمرین کامل می فهمین چی به چیه!!!