VB.NET多线程调试问题
在主线程执行的代码块设置断点,可以进行单步执行
但是在由我自己创建的工作线程中,就无法单步执行
在断点程序会中断,但只要一按F11,就立刻又进入执行状态.
看样子似乎是切换到了其他线程上.
请问有什么办法可以解决吗?
问题点数:100、回复次数:10Top
1 楼wangsaokui(无间道III(终极无间)C#MVP)回复于 2005-08-02 17:40:11 得分 0
在你的工作线程上设置多个断点,且最好减少其他线程的运行,工作线程也尽量间隔时间长些以方便调试。Top
2 楼trytoremember(忘了你 便忘了自己)回复于 2005-08-02 17:56:02 得分 0
我的其他几个线程都处在阻塞状态的
奇怪的是,我在线程调试器上把这些线程都冻结了,可还是会切过去Top
3 楼sx_lxh(路漫漫)回复于 2005-08-02 22:22:42 得分 0
关注Top
4 楼wangsaokui(无间道III(终极无间)C#MVP)回复于 2005-08-02 23:53:09 得分 0
我的其他几个线程都处在阻塞状态的
奇怪的是,我在线程调试器上把这些线程都冻结了,可还是会切过去
不要冻结,只启动一个工作线程看看Top
5 楼painchen(学习中)回复于 2005-08-03 09:44:37 得分 0
学习Top
6 楼trytoremember(忘了你 便忘了自己)回复于 2005-08-04 10:30:54 得分 0
我找到问题了,就出在下面代码中划线的一行.
s是我定义的一个侦听端口的socket,我将s赋值给给我自己定义的类clsSocket的Listener属性,然后为这个类启动一个新线程,在新线程中调用Listener的Accept方法获取传入的Socket.
因此,虽然每个线程都拥有自己独立的一个clsSocket对象,但他们的Listener属性都是指向同一个socket,估计在这里调试器没法正常工作了.不过除了不能单步执行外,似乎程序本身运行并没有什么问题.
PS,我第一次做socket和多线程的程序,我不知道这样处理是否恰当,还请各位高手们多指教!
Dim NewSocket As clsSocket
While True
AllDone.Reset()
NewSocket = New clsSocket
NewSocket.Listener = s
~~~~~~~~~~~~~~~~~~~~~~~
NewSocket.Id = i
Dim NewThread As New System.Threading.Thread(AddressOf NewSocket.Accept)
inSockets.Add(NewSocket, CStr(i))
NewThread.Name = "connection " & i
NewThread.Start()
If i > 6 Then
AllDone.WaitOne()
End If
i = i + 1
ns = Nothing
End While
Top
7 楼wangsaokui(无间道III(终极无间)C#MVP)回复于 2005-08-04 12:55:26 得分 0
我觉得你应该把下面的程序好好看看,你的思路我不是很了解,因为clsSocket类你没有给出,另外inSockets,ns等也看不出是什么东西.
[Visual Basic]
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
' State object for reading client data asynchronously
Public Class StateObject
' Client socket.
Public workSocket As Socket = Nothing
' Size of receive buffer.
Public Const BufferSize As Integer = 1024
' Receive buffer.
Public buffer(BufferSize) As Byte
' Received data string.
Public sb As New StringBuilder()
End Class 'StateObject
Public Class AsynchronousSocketListener
' Incoming data from the client.
Public Shared data As String = Nothing
' Thread signal.
Public Shared allDone As New ManualResetEvent(False)
Public Sub New()
End Sub 'New
Public Shared Sub StartListening()
' Data buffer for incoming data.
Dim bytes() As Byte = New [Byte](1024) {}
' Establish the local endpoint for the socket.
' The DNS name of the computer
' running the listener is "host.contoso.com".
Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
Dim localEndPoint As New IPEndPoint(ipAddress, 11000)
' Intializes a TCP/IP socket.
Dim listener As New Socket(AddressFamily.InterNetwork, _
SocketType.Stream, ProtocolType.Tcp)
' Bind the socket to the local endpoint and listen for incoming
' connections.
Try
listener.Bind(localEndPoint)
listener.Listen(100)
While True
' Set the event to nonsignaled state.
allDone.Reset()
' Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...")
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), _
listener)
' Wait until a connection is made before continuing.
allDone.WaitOne()
End While
Catch e As Exception
Console.WriteLine(e.ToString())
End Try
Console.WriteLine(ControlChars.Cr + "Press ENTER to continue...")
Console.Read()
End Sub 'StartListening
Public Shared Sub AcceptCallback(ar As IAsyncResult)
' Signal the main thread to continue.
allDone.Set()
' Get the socket that handles the client request.
Dim listener As Socket = CType(ar.AsyncState, Socket)
Dim handler As Socket = listener.EndAccept(ar)
' Create the state object.
Dim state As New StateObject()
state.workSocket = handler
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, _
New AsyncCallback(AddressOf ReadCallback), state)
End Sub 'AcceptCallback
Public Shared Sub ReadCallback(ar As IAsyncResult)
Dim content As [String] = [String].Empty
' Retrieve the state object and the handler socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.workSocket
' Read data from client socket.
Dim bytesRead As Integer = handler.EndReceive(ar)
If bytesRead > 0 Then
' There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, _
bytesRead))
' Check for end-of-file tag. If it is not there, read
' more data.
content = state.sb.ToString()
If content.IndexOf("<EOF>") > - 1 Then
' All the data has been read from the
' client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. " + _
ControlChars.Cr + " Data : {1}", content.Length, content)
' Echo the data back to the client.
Send(handler, content)
Else
' Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,StateObject.BufferSize, _
0, New AsyncCallback(AddressOf ReadCallback), state)
End If
End If
End Sub 'ReadCallback
Private Shared Sub Send(handler As Socket, data As [String])
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
' Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, _
New AsyncCallback(AddressOf SendCallback), handler)
End Sub 'Send
Private Shared Sub SendCallback(ar As IAsyncResult)
Try
' Retrieve the socket from the state object.
Dim handler As Socket = CType(ar.AsyncState, Socket)
' Complete sending the data to the remote device.
Dim bytesSent As Integer = handler.EndSend(ar)
Console.WriteLine("Sent {0} bytes to client.", bytesSent)
handler.Shutdown(SocketShutdown.Both)
handler.Close()
Catch e As Exception
Console.WriteLine(e.ToString())
End Try
End Sub 'SendCallback
'Entry point that delegates to C-style main Private Function.
Public Overloads Shared Sub Main()
System.Environment.ExitCode = _
Main(System.Environment.GetCommandLineArgs())
End Sub
Overloads Public Shared Function Main(args() As [String]) As Integer
StartListening()
Return 0
End Function 'Main
End Class 'AsynchronousSocketListener
Top
8 楼goldli(龙啸)回复于 2005-08-04 13:43:17 得分 0
学习Top
9 楼trytoremember(忘了你 便忘了自己)回复于 2005-08-04 15:20:07 得分 0
谢谢 wangsaokui,
我看过你给出的这个例子,实际上我的程序就是从这个例子改出来的.
修改的原因是因为原例用默认的Socket异步连接方法,虽然可以系统自动新建一个线程
但是也仅仅只建了一个线程.如果当AcceptCallback方法需要比较长时间处理时,就会阻塞
其他用户的连接.
所以我将异步连接方法改成了同步连接方法,并自建了一个类clsSocket对所有连接操作进行了封装.
在具体调用时,首先手动的创建一个线程,然后将clsSocket.Accept方法的入口地址交给这个线程,开始操作.
前面贴的代码有些乱,我整理并简化了一下如下:
Public Sub Main()
Public NewSocket As clsSocket
'alldone用以同步主线程和工作线程
Public AllDone As New System.Threading.ManualResetEvent(False)
'i 用以标识各线程的id
Dim i As Integer
'创建侦听Socket
Dim Listener = New Socket(inEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
'inEP是本地连接点,定义它的代码就省略了
Listener.bind(inEP)
Listener.listen(10)
While True
AllDone.Reset()
'定义新的连接对象
NewSocket = New clsSocket
'将侦听Socket传递给连接对象,我最初的问题就出在这个listener上,
'各个线程的Listener属性都指向它,将这句语句去掉,工作线程就能单步调试了
NewSocket.Listener = Listener
NewSocket.Id = i
Dim NewThread As New System.Threading.Thread(AddressOf NewSocket.Accept)
NewThread.Name = "connection " & i
'启动连接对象线程
NewThread.Start()
AllDone.WaitOne()
i = i + 1
End While
End Sub
Public Class clsSocket
Public Listener As Socket
Public Id As Integer
Private Handler As Socket
Public Sub Accept()
Try
'调用同步方法接受用户连接
Handler = Listener.Accept()
Console.WriteLine("Thread " & Id & " Connected!")
AllDone.Set()
'关闭连接
Handler.Shutdown(SocketShutdown.Both)
Handler.Close()
Catch ex As Exception
End Try
End Sub
End Class
Top
10 楼trytoremember(忘了你 便忘了自己)回复于 2005-08-08 11:16:59 得分 0
UP一下Top




