PDA

View Full Version : سوال: عدم اجرای برنامه از طریق thread



pooya1072
یک شنبه 17 دی 1391, 18:53 عصر
سلام
من یه برنامه چت خیلی ابتدایی ساختم . تمام برنامه مربوط به سوکت رو توی یک تابع نوشتم . در حالت عادی با اجرای برنامه سرور , فرم اصلیه برنامه قفل میشه و تا وقتی اجراست منتظره تا از کلاینت پیامی دریافت کنه . حتی برنامه رو نمیشه بست . حالا من اومدم و برنامه رو از طریق thread اجرا کنم ولی اجرا نمیشه . هم تابع اصلی و هم تابع thread رو می ذارم . ببینید می تونید منو راهنمایی کنید.

Public Sub Chat()
While OutputForm.CheckBox1.Checked = True
Try
Dim ip As IPAddress = GetMyIP()
Dim SysPort As Int32 = Convert.ToInt32(Server.txtPort.Text)
Dim TCPlistener As TcpListener = New TcpListener(ip, SysPort)
TCPlistener.Start()
Server.ListBox1.Items.Clear()
Server.ListBox1.Items.Add("The server is ruuning as port :" & Str(SysPort))
Dim MyEndpoint As IPEndPoint = CType(TCPlistener.LocalEndpoint, IPEndPoint)
Server.ListBox1.Items.Add("The local EndPoint address is :" & MyEndpoint.Address.ToString)
Server.ListBox1.Items.Add("Waiting for connectiom ...")
Dim sock As Socket = TCPlistener.AcceptSocket
MyEndpoint = CType(sock.RemoteEndPoint, IPEndPoint)
Server.ListBox1.Items.Add("Connection accepted from :" & MyEndpoint.Address.ToString)
Dim ByteData(100) As Byte
Dim size As Integer = sock.Receive(ByteData)
Server.ListBox1.Items.Add("Recieved")
Dim RecieveText As String = Nothing
For i = 0 To size
RecieveText = RecieveText & Convert.ToChar(ByteData(i))
Next
Server.ListBox1.Items.Add(RecieveText)
Dim AsciiEncod As New ASCIIEncoding
Server.ListBox1.Items.Add("Sending alert to client !")
sock.Send(AsciiEncod.GetBytes("The string was recieved by the server !"))
sock.Close()
Server.Refresh()
TCPlistener.Stop()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End While
End Sub




اینم تابع thread :



Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim t As New Threading.Thread(AddressOf Chat)
t.Start()
End Sub

the king
یک شنبه 17 دی 1391, 23:28 عصر
Thread اصلی که فرم رو نشون میده تنها Thread ای که مجاز به تغییر ظاهر فرم و دسترسی به کنترل های روی اونه،
در Thread جدیدی که ایجاد می کنید نباید مستقیما هیچ کاری با کنترل های روی فرم داشته باشید. این شیوه ای که
الان فرضا دارید روی ListBox1 انجام می دهید نباید در Thread فرعی اجرا بشه. BackgroundWorker برای اینگونه موارد
توصیه میشه.

رجوع شود به :
BackGround Worker (http://barnamenevis.org/showthread.php?353379)

این Delegate و Invoke چی هست؟ (http://barnamenevis.org/showthread.php?359005)

هر کاری که می کنم زمان پردازش کردن برنامه هام هیچ کاری روی فرم نمیتونم انجام بدم (http://barnamenevis.org/showthread.php?351236)

pooya1072
سه شنبه 19 دی 1391, 22:07 عصر
با تشکر از The King عزیز
من از راهنماییه شما استفاده کردم و مشکل اصلی حل شد . تابع Chat وقتی که توی فرم اصلیه بدون مشکل اجرا میشه. ولی وقتی اونو توی یه ماجول قرار میدم تمام مراحل بدون error اجرا میشه (این رو خط به خط چک کردم ) ولی اون قسمت نهایی که پر کردن لیست باکسه نتیجش نمایش داده نمیشه :


Imports System.Net
Imports System.Text
Imports System.Net.Sockets
 
ModuleModule1
Public ip AsIPAddress = GetMyIP()
Public TCPlistener AsTcpListener = NewTcpListener(ip, 2500)
Public Messages(7) AsString
Public IsListeningContinue AsBoolean
PublicFunction GetMyIP() AsIPAddress
Dim ip() As System.Net.IPAddress = Dns.GetHostAddresses("")
If ip.Count > 0 Then
ForEach ipadd AsIPAddressIn ip
IfNot ipadd.IsIPv6LinkLocal AndNot ipadd.IsIPv6Multicast AndNot ipadd.IsIPv6SiteLocal AndNot ipadd.IsIPv6Teredo Then
GetMyIP = ipadd
Exit Function
EndIf
Next
EndIf
ReturnIPAddress.Parse("0.0.0.0")
EndFunction
PublicSub Chat()
While IsListeningContinue = True
Try
TCPlistener.Start()
Messages(0) = "The server is ruuning as port :" & Str(2500)
Dim MyEndpoint AsIPEndPoint = CType(TCPlistener.LocalEndpoint, IPEndPoint)
Messages(1) = "The local EndPoint address is :" & MyEndpoint.Address.ToString
Messages(2) = "Waiting for connectiom ..."
Dim sock AsSocket = TCPlistener.AcceptSocket
MyEndpoint = CType(sock.RemoteEndPoint, IPEndPoint)
Messages(3) = "Connection accepted from :" & MyEndpoint.Address.ToString
Dim ByteData(100) AsByte
Dim size AsInteger = sock.Receive(ByteData)
Messages(4) = "Recieved"
Dim RecieveText AsString = Nothing
For i = 0 To size
RecieveText = RecieveText & Convert.ToChar(ByteData(i))
Next
Messages(5) = RecieveText
Dim AsciiEncod AsNewASCIIEncoding
Messages(6) = "Sending alert to client !"
sock.Send(AsciiEncod.GetBytes("The string was recieved by the server !"))
sock.Close()
Server.BackgroundWorker1.ReportProgress(1)
TCPlistener.Stop()
Catch ex AsException
MsgBox(ex.Message)
EndTry
EndWhile
EndSub
EndModule

pooya1072
سه شنبه 19 دی 1391, 22:08 عصر
این قسمت مربوط به فرم اصلیه :


Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
PublicClassServer
Public ip AsIPAddress = GetMyIP()
Public TCPlistener AsTcpListener = NewTcpListener(ip, 2500)

PrivateSub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
If CheckBox1.Checked = TrueThen IsListeningContinue = TrueElse IsListeningContinue = False
BackgroundWorker1.RunWorkerAsync()
EndSub
PrivateSub Server_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load
txtPort.Text = 2500
EndSub
PrivateSub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Chat()
EndSubPrivateSub BackgroundWorker1_ProgressChanged(ByVal sender AsObject, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
ListBox1.Items.Clear()
For i = 0 To 6
ListBox1.Items.Add(Messages(i))
Next
Me.Refresh()
EndSub