内存泄漏C#异步(得到堆栈)
我有一个应用程序,其中我将通信从TCPClient切换到使用SocketAsyncEventArgs,但我确实遇到了一个问题,当应用程序运行了几个小时后,我似乎找不到它。这是我的堆栈跟踪,有人知道吗内存泄漏C#异步(得到堆栈),c#,memory-leaks,threadpool,out-of-memory,C#,Memory Leaks,Threadpool,Out Of Memory,我有一个应用程序,其中我将通信从TCPClient切换到使用SocketAsyncEventArgs,但我确实遇到了一个问题,当应用程序运行了几个小时后,我似乎找不到它。这是我的堆栈跟踪,有人知道吗 Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.OutOfMemoryException Stac
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()
代码:
公共客户端(Form1父级)
{
todo=新的ArrayList();
buffert=新列表();
this.parent=parent;
this.ip=ini.GetFromIni(“CONFIG”,“ip”);
this.port=ini.GetFromIni(“配置”、“端口”);
数据=新字节[100000];
//主机的地址。
IPAddress[]addressList=host.addressList;
//实例化端点和套接字。
this.hostEndPoint=new-IPEndPoint(addressList[addressList.Length-1],Convert.ToInt32(port));
this.clientSocket=新套接字(this.hostEndPoint.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
startTimer=new System.Timers.Timer();
startTimer.Appead+=新的ElapsedEventHandler(startSendLoop);
起始时间间隔=1000;
startTimer.Start();
sendTimer=新系统.Timers.Timer();
sendTimer.Appead+=新的ElapsedEventHandler(sendloop);
sendTimer.Interval=500;
sendTimer.Start();
pingTimer=新的System.Timers.Timer();
pingTimer.appeased+=新的ElapsedEventHandler(pingTimer\u appeased);
pingTimer.Interval=13000;
pingTimer.Start();
}
内部空断开()
{
尝试
{
clientSocket.Disconnect(正确);
}
捕获(例外e)
{
System.Diagnostics.Debug.WriteLine(如ToString());
Show(例如ToString());
}
}
公共空间处置()
{
尝试
{
autoConnectEvent.Close();
autoSendReceiveEvents[SendOperation].Close();
autoSendReceiveEvents[ReceiveOperation].Close();
if(this.clientSocket.Connected)
{
this.clientSocket.Close();
}
}
捕获(例外情况除外)
{
}
}
公共无效pingTimer_已过(对象发送器,ElapsedEventArgs e)
{
sendPing=true;
}
public void startSendLoop(对象发送方,ElapsedEventArgs e)
{
尝试
{
如果(!this.clientSocket.Connected)
{
connectArgs=new SocketAsyncEventArgs();
connectArgs.UserToken=this.clientSocket;
connectArgs.RemoteEndPoint=this.hostEndPoint;
connectArgs.Completed+=新事件处理程序(OnConnect);
ConnectAsync(connectArgs);
布尔测试=自动连接事件。WaitOne(5000);
gotData=true;
lastTime=DateTime.Now;
}
}
捕获(例外情况除外)
{
System.Diagnostics.Debug.WriteLine(例如ToString());
}
}
私有void进程错误(SocketAsyncEventArgs e)
{
sockets=e.UserToken作为Socket;
如果(已连接)
{
//关闭与客户端关联的套接字
尝试
{
s、 关机(SocketShutdown.Both);
}
捕获(例外)
{
//如果客户端进程已关闭,则引发
}
最后
{
如果(已连接)
{
s、 Close();
}
}
}
}
连接上的专用void(对象发送方,SocketAsyncEventArgs e)
{
尝试
{
autoConnectEvent.Set();
//为已连接的套接字设置标志。
this.connected=(e.SocketError==SocketError.Success);
}
捕获(例外情况除外)
{
}
}
私有void OnReceive(对象发送方,SocketAsyncEventArgs e)
{
尝试
{
while(true)
{
如果(可以接收)
{
canReceive=false;
字符串数据;
int recv=0;
for(int i=0;i0)
{
整数计数=0;
for(int i=0;ipublic 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;
}
}