我有一个应用程序,我将通信从 TCPClient 切换到使用 SocketAsyncEventArgs,但是当应用程序运行几个小时时,我确实遇到了一个问题,我似乎找不到它。这是我的堆栈跟踪,有人知道吗?:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.OutOfMemoryException
Stack:
at System.Threading.ThreadPoolWorkQueue.Enqueue(System.Threading.IThreadPoolWorkItem, Boolean)
at System.Threading.ThreadPool.QueueUserWorkItemHelper(System.Threading.WaitCallback, System.Object, System.Threading.StackCrawlMark ByRef, Boolean)
at System.Threading.ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, System.Object)
at System.IO.Ports.SerialStream+EventLoopRunner.CallEvents(Int32)
at System.IO.Ports.SerialStream+EventLoopRunner.WaitForCommEvent()
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
代码:
public Client(Form1 parent)
{
todo = new ArrayList();
buffert = new List<MsgStruct>();
this.parent = parent;
this.ip = ini.GetFromIni("CONFIG", "IP");
this.port = ini.GetFromIni("CONFIG", "PORT");
data = new byte[100000];
// Addres of the host.
IPAddress[] addressList = host.AddressList;
// Instantiates the endpoint and socket.
this.hostEndPoint = new IPEndPoint(addressList[addressList.Length - 1], Convert.ToInt32(port));
this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
startTimer = new System.Timers.Timer();
startTimer.Elapsed += new ElapsedEventHandler(startSendLoop);
startTimer.Interval = 1000;
startTimer.Start();
sendTimer = new System.Timers.Timer();
sendTimer.Elapsed += new ElapsedEventHandler(sendloop);
sendTimer.Interval = 500;
sendTimer.Start();
pingTimer = new System.Timers.Timer();
pingTimer.Elapsed += new ElapsedEventHandler(pingTimer_Elapsed);
pingTimer.Interval = 13000;
pingTimer.Start();
}
internal void Disconnect()
{
try
{
clientSocket.Disconnect(true);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.ToString());
MessageBox.Show(e.ToString());
}
}
public void Dispose()
{
try
{
autoConnectEvent.Close();
autoSendReceiveEvents[SendOperation].Close();
autoSendReceiveEvents[ReceiveOperation].Close();
if (this.clientSocket.Connected)
{
this.clientSocket.Close();
}
}
catch (Exception ex)
{
}
}
public void pingTimer_Elapsed(object sender, ElapsedEventArgs e)
{
sendPing = true;
}
public void startSendLoop(object sender, ElapsedEventArgs e)
{
try
{
if (!this.clientSocket.Connected)
{
connectArgs = new SocketAsyncEventArgs();
connectArgs.UserToken = this.clientSocket;
connectArgs.RemoteEndPoint = this.hostEndPoint;
connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
clientSocket.ConnectAsync(connectArgs);
bool test = autoConnectEvent.WaitOne(5000);
gotData = true;
lastTime = DateTime.Now;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
private void ProcessError(SocketAsyncEventArgs e)
{
Socket s = e.UserToken as Socket;
if (s.Connected)
{
// close the socket associated with the client
try
{
s.Shutdown(SocketShutdown.Both);
}
catch (Exception)
{
// throws if client process has already closed
}
finally
{
if (s.Connected)
{
s.Close();
}
}
}
}
private void OnConnect(object sender, SocketAsyncEventArgs e)
{
try
{
autoConnectEvent.Set();
// Set the flag for socket connected.
this.connected = (e.SocketError == SocketError.Success);
}
catch (Exception ex)
{
}
}
private void OnReceive(object sender, SocketAsyncEventArgs e)
{
try
{
while (true)
{
if (canReceive)
{
canReceive = false;
string stringData;
int recv = 0;
for (int i = 0; i < e.Buffer.Length; i++)
{
if (e.Buffer[i] != 0)
recv++;
else
break;
}
if (recv > 0)
{
int count = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] != 0)
count++;
else
break;
}
e.Buffer.CopyTo(data, count);
lastTime = DateTime.Now;
gotData = true;
if ((byte)data[count + recv - 1] == (byte)255)
{
int cnt = -1;
for (int i = 0; i < count + recv; i++)
{
if (data[i] == (byte)254)
{
cnt = i;
break;
}
}
int nr = (count + recv) - cnt - 2;
byte[] tmp = new byte[nr];
for (int i = 0; i < nr; i++)
{
tmp[i] = data[cnt + i + 1];
}
string crc = Encoding.UTF8.GetString(tmp);
stringData = Encoding.UTF8.GetString(data, 0, cnt);
MsgStruct msgs = new MsgStruct(stringData);
msgs.setCrc(crc);
todo.Add(msgs);
data = new byte[100000];
}
}
canReceive = true;
break;
}
else
Thread.Sleep(10);
}
handleToDo();
autoSendReceiveEvents[SendOperation].Set();
e.Dispose();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
private void OnSend(object sender, SocketAsyncEventArgs e)
{
try
{
// Signals the end of send.
sendSuccess = true;
autoSendReceiveEvents[ReceiveOperation].Set();
if (e.SocketError == SocketError.Success)
{
if (e.LastOperation == SocketAsyncOperation.Send)
{
// Prepare receiving.
Socket s = e.UserToken as Socket;
byte[] receiveBuffer = new byte[100000];
e.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
s.ReceiveAsync(e);
}
}
else
{
this.ProcessError(e);
}
}
catch (Exception ex)
{
}
}
public void sendloop(object sender, ElapsedEventArgs e)
{
try
{
sendTimer.Enabled = false;
if (this.clientSocket.Connected)
{
byte[] data = new byte[1024];
bool extendedTime = false;
DateTime tmpDate = lastTime.AddSeconds(30);
if (DateTime.Now > tmpDate)
{
gotData = false;
}
if (canUseBuffert && sendSuccess)
{
canUseBuffert = false;
if (buffert.Count > 0)
{
if (buffert[0] != null && buffert[0].getMsg().Length != 0)
{
byte[] ba = Encoding.UTF8.GetBytes(buffert[0].getMsg());
if (buffert[0].getCrc() == "")
{
ulong tmp = CRC.calc_crc(ba, ba.Length);
buffert[0].setCrc(tmp.ToString("X"));
}
if (buffert[0].canSendByTimeout())
{
string crcStr = "?" + buffert[0].getCrc() + "?";
byte[] bb = Encoding.UTF8.GetBytes(crcStr);
crcStr = Encoding.UTF8.GetString(bb);
byte[] fullMsg = new byte[ba.Length + bb.Length];
bb[0] = 254;
bb[bb.Length - 1] = 255;
ba.CopyTo(fullMsg, 0);
bb.CopyTo(fullMsg, ba.Length);
string s = System.Text.UTF8Encoding.ASCII.GetString(fullMsg);
this.clientSocket.NoDelay = false;
completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(fullMsg, 0, fullMsg.Length);
completeArgs.UserToken = this.clientSocket;
completeArgs.RemoteEndPoint = this.hostEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
sendSuccess = false;
// Start sending asyncronally.
clientSocket.SendAsync(completeArgs);
}
}
}
else
{
extendedTime = true;
byte[] bba = Encoding.UTF8.GetBytes("X");
this.clientSocket.NoDelay = true;
completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(bba, 0, bba.Length);
completeArgs.UserToken = this.clientSocket;
completeArgs.RemoteEndPoint = this.hostEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
sendSuccess = false;
// Start sending asyncronally.
clientSocket.SendAsync(completeArgs);
}
}
canUseBuffert = true;
if (!clientSocket.Connected && !gotData)
Disconnect();
}
sendTimer.Enabled = true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
sendTimer.Enabled = true;
}
}