线程冻结 [英] thread frozen
问题描述
我开始一个新线程(前一个是线程计时)因为我已经隔离了我的问题。
>
它与调用非托管C ++代码无关(我在
测试应用程序中将其删除)。
我有一个线程_itTaskThread运行。
应用程序正在侦听TCP端口。
它接受来自客户端的2个连接。
我模拟客户端崩溃(使用Debug-> StopDebugging)。
我得到了一个Sockets.SocketException。 (正如预期的那样)但似乎冻结了我的_itTaskThread线程超过3秒!
为什么这个线程被冻结,它与Tcp套接字无关
处理!
参见代码+下面的日志:
预先感谢您的帮助,
Droopy。
应用程序(WinForms with一个OK按钮)
Form1.cs
--------
....
private ManualResetEvent _itTaskEvent = new ManualResetEvent(false);
private TimeSpan _maxItTaskElapsedTime = TimeSpan.MinValue;
private TimeSpan _minItTaskElapsedTime = TimeSpan.MaxValue;
private Tcp _tcp;
private System.Windows.Forms.Button buttonOK;
private Thread _itTaskThread = null; < br $>
....
public Form1()
{
InitializeComponent();
_tcp = new Tcp();
_tcp.OnCommandReceived + = new Tcp.CommandReceivedHandler
(CommandReceivedHandler);
_ itTaskThread = new Thread(new ThreadStart(ItTaskProc));
_itTaskThread.Name =" ItTask thread";
_itTaskThread.Priority = ThreadPriority.Highest;
_itTaskThread.Start();
}
....
public void ItTaskProc()
{
Util.TraceLine(ItTaskProc线程开始);
DateTime dtCurrent = DateTime.Now;
DateTime dtLast = DateTime.MinValue;
尝试
{
while(true)
{
Util.TraceLine(在WaitOne之前);
if(_itTaskEvent.WaitOne(25,false))
{
Util.TraceLine(ItTaskProc结束问);
休息;
}
Util.TraceLine("在WaitOne之后);
Util.TraceLine(在ItTaskProc之前);
Util.TraceLine(" _serialChannel.ItTask()");
Util.TraceLine(ItTaskProc之后);
dtLast = dtCurrent;
dtCurrent = DateTime.Now;
Util.TraceLine(" dtCurrent =" + dtCurrent.ToString(" HH:mm:ss:fff:
")+
",dtLast =" + dtLast.ToString(" HH:mm:ss:fff:"));
TimeSpan diff = dtCurrent.Subtract(dtLast);
if(_minItTaskElapsedTime> ;差异)
{
_minItTaskElapsedTime = diff;
Util.TraceLine(" New mininimum ItTaskElapsedTime =" +
_minItTaskElapsedTime);
}
if(_maxItTaskElapsedTime< diff)
{
_maxItTaskElapsedTime = diff ;
Util.TraceLine(" New maximum ItTaskElapsedTime =" +
_maxItTaskElapsedTime);
}
}
}
catch(ThreadAbortException abortException)
{
Util.TraceLine(" ItTaskProc:Thread aborted" ;);
}
catch(例外情况)
{
Util.TraceLine(" ItTaskProc:捕获异常:+ ex);
}
最后
{
_itTaskEvent.Reset();
}
Util.TraceLine(&ItTaskProc结束了gracef) ully);
}
public bool CommandReceivedHandler(对象发送者,TcpInfoEventArgs
tcpInfo)
{
bool continueReading = true;
Util.TraceLine
(" CommandCoordinator:CommandReceivedHandler tcpInfo =" + tcpInfo);
返回continueReading;
}
private void CloseApp()
{
_itTaskEvent.Set();
_tcp.Close();
}
私人void buttonOK_Click(object sender,System.EventArgs e)
{
CloseApp();
Application.Exit();
}
Tcp.cs
------
使用System;
使用System.Net;
使用System.Net.Sockets;
使用System.Threading;
使用System.IO;
使用System.Text;
名称空间IPRManaged
{
//发布/订阅导出收到的命令
// ---------- TcpInfoEventArgs ----------
公共类TcpInfoEventArgs:EventArgs
{
private byte [] _buffer;
private int _bytesRead = 0;
public TcpInfoEventArgs(byte [] buffer,int bytesRead)
{
_buffer = buffer;
_bytesRead = bytesRead;
}
公共覆盖字符串ToString()
{
return" TcpInfoEventArgs #read =" + _bytesRead;
}
public int BytesRead
{
get {return _bytesRead; }
}
公共字节[]缓冲区
{
get {return _buffer; }
}
}
公共类Tcp
{
private const int PORT = 1414;
private Socket _server;
private Thread _listeningThread = null;
private bool _mustRun = true;
private bool _continueReading = true;
//发布/订阅导出收到的命令
public delegate bool CommandReceivedHandler(object sender,
TcpInfoEventArgs tcpInfo);
公共事件CommandReceivedHandler OnCommandReceived;
//线程信号。
private static ManualResetEvent _allDone = new ManualResetEvent
(false);
public Tcp()
{
_listeningThread = new线程(新的ThreadStart(RunServer));
_listeningThread.Name =" TCP Listening thread" ;;
_listeningThread.Start();
}
public void关闭()
{
_mustRun = false;
_allDone .Set();
//不应该需要
if(_listeningThread!= null)
_listeningThread.Abort();
}
public void RunServer()
{
try
{
_server = new Socket
(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
IPEndPoint iep =新IPEndPoint(IPAddress.Any,PORT);
_server.Bind(iep);
_server.Listen(5);
Util.TraceLine(TCP服务器侦听端口#; (PORT);
while(_mustRun)
{
//将事件设置为无信号状态。
_allDone.Reset();
_server.BeginAccept(new AsyncCallback(AcceptConnection),
_server);
//等到连接完成后再继续。
_allDone.WaitOne();
}
}
catch(例外情况)
{
Util.TraceLine(" RunServer:Exception catched" + ex.Message);
}
_listeningThread = null;
Util.TraceLine(" RunServer:thread finished");
}
void AcceptConnection(IAsyncResult iar)
{
套接字服务器=(套接字)iar.AsyncState;
Socket client = server.EndAccept(iar);
Util.TraceLine(" TCP Server:从客户端接受的连接:" +
client.RemoteEndPoint.ToString() +" on" +
client.LocalEndPoint.ToString());
//发出主线程信号继续。
_allDone.Set();
//创建状态对象。
StateObject state = new StateObject();
state.clientSocket = client;
Util.TraceLine(" Tcp:AcceptConnection:接受客户= +
client.RemoteEndPoint.ToString()+" ...");
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
new AsyncCallback(ReadCallback),state);
}
public void ReadCallback(IAsyncResult ar)
{
//检索状态对象和处理程序套接字
//来自异步状态对象。
StateObject state =(StateObject)ar.AsyncState;
套接字处理程序=状态。 clientSocket;
Util.TraceLine(" Tcp:ReadCallback:从客户端接收=> +
handler.RemoteEndPoint.ToString()+" ..." );
尝试
{
//从客户端套接字读取数据。
int bytesRead = handler.EndReceive(ar);
if(bytesRead> 0)
{
Util.TraceLine(" ; ReadCallback:" + bytesRead +"字节收到
for client ="
+ handler.RemoteEndPoint.ToString()+
on+ handler.Loc alEndPoint.ToString());
StringBuilder iprlibIn = new StringBuilder(" IPRLIB:IN:");
for(int i = 0;我< bytesRead; i ++)
{
iprlibIn.Append(" [" + i +"] =" + state.buffer [i] .ToString
(" X2")+"");
}
Util.TraceLine(iprlibIn.ToString());
if(OnCommandReceived == null)
Util.TraceLine(" TcpConnection:运行没有定义的订户以获得
命令);
else
{
TcpInfoEventArgs tcpInfo = new TcpInfoEventArgs(state.buffer,
bytesRead);
_continueReading = OnCommandReceived(this,tcpInfo);
}
Util.TraceLine(" ReadCallback:continueReading =" +
_continueReading +
" for client ="
+ handler.RemoteEndPoint.ToString()+
" on " + handler.LocalEndPoint.ToString());
if(_continueReading)
handler.BeginReceive(state.buffer,0,StateObject.BufferSize, 0,
新的AsyncCallback(阅读回调),州);
}
其他
{
Util.TraceLine(" ReadCallback:no字节读取,停止读取);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
handler = null ;
}
}
catch(例外情况)
{
Util .TraceLine(" ReadCallback:Exception catched:" + ex.ToString
());
}
if(handler!= null)
Util.TraceLine(" ReadCallback:处理完成客户端="
+ handler.RemoteEndPoint.ToString()+
" on" + handler。 LocalEndPoint.ToString());
}
public static void SendCallback(IAsyncResult ar)
{
try
{
//从状态对象中检索套接字。
套接字处理程序=(套接字)ar.AsyncState;
//完成将数据发送到远程设备。
int bytesSent = handler.EndSend(ar);
Util。 TraceLine(" SendCallback:Sent" + bytesSent +" bytes to
client =" +
handler.RemoteEndPoint.ToString()+
" on" + handler.LocalEndPoint.ToString());
}
catch(例外e)
{
Util.TraceLine(e.ToString());
}
}
}
// ---------- StateObject ----------
//用于异步读取客户端数据的状态对象
公共类StateObject
{
//客户端套接字。
public Socket clientSocket = null;
//接收缓冲区的大小。
public const int BufferSize = 1024;
//接收缓冲区。
public byte [] buffer = new byte [BufferSize];
}
}
日志(见10:09:39:015和10:09:42:500之间的问题)
----
.... >
10:09:38:984:ItTask主题:在WaitOne之前
10:09:39:000:ItTask主题:在WaitOne之后
10:09 :39:000:ItTask线程:ItTaskProc之前
10:09:39:000:ItTask线程:_serialChannel.ItTask()
10:09:39:000: ItTask线程:在ItTaskProc之后
10:09:39:000:ItTask thread:dtCurrent = 10:09:39:000:,
dtLast = 10:09:38 :968:
10:09:39:000:ItTask thread:be前一个WaitOne
10:09:39:015 :: Tcp:ReadCallback:从客户收到=
127.0.0.1:3417 ...
10:09:42:500:ItTask线程:在WaitOne之后
10:09:42:515:ItTask线程:在ItTaskProc之前
10:09:42:515 :ItTask线程:_serialChannel.ItTask()
10:09:42:515:ItTask线程:ItTaskProc之后
10:09:42:515:ItTask线程:dtCurrent = 10:09:42:515:,
dtLast = 10:09:39:000:
10:09:42:515:ItTask线程:新的最大ItTaskElapsedTime =
00:00:03.5156250
10:09:42:531:ItTask主题:在WaitOne之前
10:09:42:531 :: ReadCallback:异常捕获:
System.Net.Sockets.SocketException:Une connexion存在广告? être
$ b $bferméeparl''h遥远的
在System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
在IPRManaged .Tcp.ReadCallback(IAsyncResult ar)in
c:\ temp\testipr\windowsapplication\tcp.cs:line 157
10:09:42:531 :: ReadCallback:处理完成客户端=
127.0.0.1:3417,127.0.0.1:1414
10:09:42:531 :: Tcp:ReadCallback:Receiving来自客户=
127.0.0.1:3416 ...
10:09:42:531 :: ReadCallback:异常捕获:
系统.Net.Sockets.SocketException:Une connexion存在广告? être
$ b $bferméeparl''h遥远的
在System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
在IPRManaged .Tcp.ReadCallback(IAsyncResult ar)in
c:\ temp\testipr\windowsapplication\tcp.cs:line 157
10:09:42:531 :: ReadCallback:处理完成客户端=
127.0.0.1:3416,127.0.0.1:1414
10:09:42:546:ItTask线程:在WaitOne之后
10:09:42:546:ItTask线程:在ItTaskProc之前
10:09:42:546:ItTask线程:_serialChannel.ItTask()
10:09:42:546:ItTask线程:在ItTaskProc之后
10:09:42:546:ItTask thread:dtCurrent = 10:09:42:546:,
dtLast = 10:09:42:515:
....
请问有什么想法吗?
***通过Developersdex发送 http://www.developersdex.com ***
不要st参加USENET ...获得奖励!
" Droopy Toon" <博士******** @ ibelgique.com>在消息中写道
新闻:Os ************** @ TK2MSFTNGP11.phx.gbl ...请问有什么想法?
他们的吨。
好的,请告诉我。
我真的需要一个解决这个问题的方法。
***通过Developersdex发送 http://www.developersdex.com ***
不要只是参加USENET ......获得奖励!
Hi,
I start a new thread (previous one was "thread timing") because I have
isolated my problem.
It has nothing to do with calling unmanaged C++ code (I removed it in a
test application).
I have a thread "_itTaskThread" running.
The application is listening on a TCP port.
It accepts 2 connection from a client.
I simulate a crash on the client side (using "Debug->StopDebugging").
I got a "Sockets.SocketException" (as expected) but it seems to freeze
my "_itTaskThread" thread for more than 3 seconds !
Why does this thread is frozen, it has nothing to do with Tcp socket
handling !
See code + logs here below :
Thanks in advance for your help,
Droopy.
Application (WinForms with a "OK" push button)
Form1.cs
--------
....
private ManualResetEvent _itTaskEvent = new ManualResetEvent (false);
private TimeSpan _maxItTaskElapsedTime = TimeSpan.MinValue;
private TimeSpan _minItTaskElapsedTime = TimeSpan.MaxValue;
private Tcp _tcp;
private System.Windows.Forms.Button buttonOK;
private Thread _itTaskThread = null;
....
public Form1()
{
InitializeComponent();
_tcp = new Tcp ();
_tcp.OnCommandReceived += new Tcp.CommandReceivedHandler
(CommandReceivedHandler);
_itTaskThread = new Thread (new ThreadStart (ItTaskProc));
_itTaskThread.Name = "ItTask thread";
_itTaskThread.Priority = ThreadPriority.Highest;
_itTaskThread.Start ();
}
....
public void ItTaskProc ()
{
Util.TraceLine ("ItTaskProc thread started");
DateTime dtCurrent = DateTime.Now;
DateTime dtLast = DateTime.MinValue;
try
{
while (true)
{
Util.TraceLine ("before WaitOne");
if (_itTaskEvent.WaitOne (25, false))
{
Util.TraceLine ("ItTaskProc end asked");
break;
}
Util.TraceLine ("after WaitOne");
Util.TraceLine ("before ItTaskProc");
Util.TraceLine ("_serialChannel.ItTask ()");
Util.TraceLine ("after ItTaskProc");
dtLast = dtCurrent;
dtCurrent = DateTime.Now;
Util.TraceLine ("dtCurrent=" + dtCurrent.ToString ("HH:mm:ss:fff:
") +
", dtLast=" + dtLast.ToString ("HH:mm:ss:fff: "));
TimeSpan diff = dtCurrent.Subtract (dtLast);
if (_minItTaskElapsedTime > diff)
{
_minItTaskElapsedTime = diff;
Util.TraceLine ("New mininimum ItTaskElapsedTime = " +
_minItTaskElapsedTime);
}
if (_maxItTaskElapsedTime < diff)
{
_maxItTaskElapsedTime = diff;
Util.TraceLine ("New maximum ItTaskElapsedTime = " +
_maxItTaskElapsedTime);
}
}
}
catch(ThreadAbortException abortException)
{
Util.TraceLine ("ItTaskProc: Thread aborted");
}
catch (Exception ex)
{
Util.TraceLine ("ItTaskProc: Exception catched: " + ex);
}
finally
{
_itTaskEvent.Reset ();
}
Util.TraceLine ("ItTaskProc ended gracefully");
}
public bool CommandReceivedHandler (object sender, TcpInfoEventArgs
tcpInfo)
{
bool continueReading = true;
Util.TraceLine
("CommandCoordinator:CommandReceivedHandler tcpInfo = " + tcpInfo);
return continueReading;
}
private void CloseApp ()
{
_itTaskEvent.Set ();
_tcp.Close ();
}
private void buttonOK_Click(object sender, System.EventArgs e)
{
CloseApp ();
Application.Exit ();
}
Tcp.cs
------
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Text;
namespace IPRManaged
{
// publish/subscribe to export received command
// ---------- TcpInfoEventArgs ----------
public class TcpInfoEventArgs : EventArgs
{
private byte [] _buffer;
private int _bytesRead = 0;
public TcpInfoEventArgs (byte [] buffer, int bytesRead)
{
_buffer = buffer;
_bytesRead = bytesRead;
}
public override string ToString()
{
return "TcpInfoEventArgs #read = " + _bytesRead;
}
public int BytesRead
{
get { return _bytesRead; }
}
public byte [] Buffer
{
get { return _buffer; }
}
}
public class Tcp
{
private const int PORT = 1414;
private Socket _server;
private Thread _listeningThread = null;
private bool _mustRun = true;
private bool _continueReading = true;
// publish/subscribe to export received command
public delegate bool CommandReceivedHandler (object sender,
TcpInfoEventArgs tcpInfo);
public event CommandReceivedHandler OnCommandReceived;
// Thread signal.
private static ManualResetEvent _allDone = new ManualResetEvent
(false);
public Tcp ()
{
_listeningThread = new Thread (new ThreadStart (RunServer));
_listeningThread.Name = "TCP Listening thread";
_listeningThread.Start ();
}
public void Close ()
{
_mustRun = false;
_allDone.Set ();
// should not be needed
if (_listeningThread != null)
_listeningThread.Abort ();
}
public void RunServer ()
{
try
{
_server = new Socket
(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint (IPAddress.Any, PORT);
_server.Bind (iep);
_server.Listen (5);
Util.TraceLine ("TCP Server listening on port #" + PORT);
while (_mustRun)
{
// Set the event to nonsignaled state.
_allDone.Reset ();
_server.BeginAccept (new AsyncCallback (AcceptConnection),
_server);
// Wait until a connection is made before continuing.
_allDone.WaitOne ();
}
}
catch (Exception ex)
{
Util.TraceLine ("RunServer: Exception catched " + ex.Message);
}
_listeningThread = null;
Util.TraceLine ("RunServer: thread finished");
}
void AcceptConnection (IAsyncResult iar)
{
Socket server = (Socket) iar.AsyncState;
Socket client = server.EndAccept (iar);
Util.TraceLine ("TCP Server: connection accepted from client: " +
client.RemoteEndPoint.ToString() + " on " +
client.LocalEndPoint.ToString ());
// Signal the main thread to continue.
_allDone.Set ();
// Create the state object.
StateObject state = new StateObject ();
state.clientSocket = client;
Util.TraceLine ("Tcp:AcceptConnection: Accepting for client = " +
client.RemoteEndPoint.ToString () + " ...");
client.BeginReceive (state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback (ReadCallback), state);
}
public void ReadCallback (IAsyncResult ar)
{
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.clientSocket;
Util.TraceLine ("Tcp:ReadCallback: Receiving from client = " +
handler.RemoteEndPoint.ToString () + " ...");
try
{
// Read data from the client socket.
int bytesRead = handler.EndReceive (ar);
if (bytesRead > 0)
{
Util.TraceLine ("ReadCallback: " + bytesRead + " bytes received
for client = "
+ handler.RemoteEndPoint.ToString () +
" on " + handler.LocalEndPoint.ToString ());
StringBuilder iprlibIn = new StringBuilder ("IPRLIB:IN:");
for (int i = 0; i < bytesRead; i++)
{
iprlibIn.Append ("[" + i + "] = " + state.buffer [i].ToString
("X2") + " ");
}
Util.TraceLine (iprlibIn.ToString ());
if (OnCommandReceived == null)
Util.TraceLine ("TcpConnection:Run no subscriber defined to get
the command");
else
{
TcpInfoEventArgs tcpInfo = new TcpInfoEventArgs (state.buffer,
bytesRead);
_continueReading = OnCommandReceived (this, tcpInfo);
}
Util.TraceLine ("ReadCallback: continueReading = " +
_continueReading +
" for client = "
+ handler.RemoteEndPoint.ToString () +
" on " + handler.LocalEndPoint.ToString ());
if (_continueReading)
handler.BeginReceive (state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback (ReadCallback), state);
}
else
{
Util.TraceLine ("ReadCallback: no byte read, stop reading");
handler.Shutdown (SocketShutdown.Both);
handler.Close ();
handler = null;
}
}
catch (Exception ex)
{
Util.TraceLine ("ReadCallback: Exception catched: " + ex.ToString
());
}
if (handler != null)
Util.TraceLine ("ReadCallback: handling finished for client = "
+ handler.RemoteEndPoint.ToString () +
" on " + handler.LocalEndPoint.ToString ());
}
public static void SendCallback (IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend (ar);
Util.TraceLine ("SendCallback: Sent " + bytesSent + " bytes to
client = " +
handler.RemoteEndPoint.ToString () +
" on " + handler.LocalEndPoint.ToString ());
}
catch (Exception e)
{
Util.TraceLine (e.ToString());
}
}
}
// ---------- StateObject ----------
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket clientSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte [BufferSize];
}
}
Logs (see the problem between 10:09:39:015 and 10:09:42:500)
----
....
10:09:38:984: ItTask thread: before WaitOne
10:09:39:000: ItTask thread: after WaitOne
10:09:39:000: ItTask thread: before ItTaskProc
10:09:39:000: ItTask thread: _serialChannel.ItTask ()
10:09:39:000: ItTask thread: after ItTaskProc
10:09:39:000: ItTask thread: dtCurrent=10:09:39:000: ,
dtLast=10:09:38:968:
10:09:39:000: ItTask thread: before WaitOne
10:09:39:015: : Tcp:ReadCallback: Receiving from client =
127.0.0.1:3417 ...
10:09:42:500: ItTask thread: after WaitOne
10:09:42:515: ItTask thread: before ItTaskProc
10:09:42:515: ItTask thread: _serialChannel.ItTask ()
10:09:42:515: ItTask thread: after ItTaskProc
10:09:42:515: ItTask thread: dtCurrent=10:09:42:515: ,
dtLast=10:09:39:000:
10:09:42:515: ItTask thread: New maximum ItTaskElapsedTime =
00:00:03.5156250
10:09:42:531: ItTask thread: before WaitOne
10:09:42:531: : ReadCallback: Exception catched:
System.Net.Sockets.SocketException: Une connexion existante a d? être
fermée par l''h?te distant
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at IPRManaged.Tcp.ReadCallback(IAsyncResult ar) in
c:\temp\testipr\windowsapplication\tcp.cs:line 157
10:09:42:531: : ReadCallback: handling finished for client =
127.0.0.1:3417 on 127.0.0.1:1414
10:09:42:531: : Tcp:ReadCallback: Receiving from client =
127.0.0.1:3416 ...
10:09:42:531: : ReadCallback: Exception catched:
System.Net.Sockets.SocketException: Une connexion existante a d? être
fermée par l''h?te distant
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at IPRManaged.Tcp.ReadCallback(IAsyncResult ar) in
c:\temp\testipr\windowsapplication\tcp.cs:line 157
10:09:42:531: : ReadCallback: handling finished for client =
127.0.0.1:3416 on 127.0.0.1:1414
10:09:42:546: ItTask thread: after WaitOne
10:09:42:546: ItTask thread: before ItTaskProc
10:09:42:546: ItTask thread: _serialChannel.ItTask ()
10:09:42:546: ItTask thread: after ItTaskProc
10:09:42:546: ItTask thread: dtCurrent=10:09:42:546: ,
dtLast=10:09:42:515:
....
Any idea please ?
*** Sent via Developersdex http://www.developersdex.com ***
Don''t just participate in USENET...get rewarded for it!
"Droopy Toon" <dr********@ibelgique.com> wrote in message
news:Os**************@TK2MSFTNGP11.phx.gbl...Any idea please ?
Tons of them.
OK, just let me know.
I really need a solution for this problem.
*** Sent via Developersdex http://www.developersdex.com ***
Don''t just participate in USENET...get rewarded for it!
这篇关于线程冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!