我有一个Winform应用程序,它使用Pcapdot.Net DLL并播放Pcap文件。 当我在循环中播放文件时,我可以看到应用程序内存被引发直到发生崩溃,并且在堆栈跟踪中我可以看到这发生在播放文件的方法中。 所以我想添加dispose方法,看看它是否可以解决这个崩溃问题。
所以我在班上添加了一个变量private bool _disposed;
和方法:
public void Dispose()
{
Dispose(true);
}
private virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
_disposed = true;
}
}
我的播放方法:
public bool sendBuffer(PacketDevice packetDevice)
{
int count = 0;
bool bContinuePlay = true;
PacketDevice selectedOutputDevice = packetDevice;
_shouldContinue = true;
_isStop = true;
_stopButton = true;
OfflinePacketDevice selectedInputDevice = new OfflinePacketDevice(_filePath.FullName); //open the capture file
DateTime time = DateTime.Now;
double totalTime = 0;
double totalDelayTime = 0;
double deletaTime = 0;
using (inputCommunicator = selectedInputDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
using (OutputCommunicator = selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
ThreadStart tStarter = delegate { openAdapterForStatistics(selectedOutputDevice); };
Thread thread = new Thread(tStarter);
thread.IsBackground = true;
thread.Start();
DateTime lastTime = DateTime.MinValue;
double delayTime = 0;
Packet packet;
IEnumerable<Packet> packets;
while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok && _isStop) //fill the buffer with the packets from the file
{
if (count < _numberOfPacketsInfile)
{
using (PacketSendBuffer mSendBuffer = new PacketSendBuffer((uint)packet.Length * 4))
{
if (_isBurst)
{
if (lastTime != DateTime.MinValue)
{
if (packet != null)
{
delayTime = (packet.Timestamp.Subtract(lastTime).TotalMilliseconds) / _playSpeed; //delay between packets
}
if (delayTime > 1000)
{
if (_startTimer != null)
{
_startTimer(delayTime, EventArgs.Empty);
}
_delayForNextPacket = delayTime;
}
totalDelayTime += delayTime;
delayTime = delayTime - deletaTime;
if (delayTime < 0)
{
delayTime = 0;
}
if (evePacketProgress != null)
{
int packetProgressPrecentage = (int)(((double)_numberOfSendPackets / _numberOfPacketsInfile) * 100);
evePacketProgress(packetProgressPrecentage);
}
_mrEvent.WaitOne((int)delayTime);
if (_stopTimer != null)
{
_stopTimer(delayTime, EventArgs.Empty);
}
} //end if
} // end if _brust
if (_fragmentation)
{
foreach (Packet item in splitPacket(packet, 1))
{
mSendBuffer.Enqueue(item);
}
}
else if (packet != null)
{
lastTime = packet.Timestamp;
mSendBuffer.Enqueue(packet);
}
if (evePacketProgress != null)
{
int packetProgressPrecentage = (int)(((double)_numberOfSendPackets / _numberOfPacketsInfile) * 100);
evePacketProgress(packetProgressPrecentage);
}
try
{
OutputCommunicator.Transmit(mSendBuffer, _isBurst); //send the packet
_numberOfSendPackets++;
}
catch (Exception)
{
}
}///
totalTime = DateTime.Now.Subtract(time).TotalMilliseconds;
deletaTime = totalTime - totalDelayTime;
count++;
}
} //end while
}
}
return bContinuePlay;
}
崩溃发生在DateTime lastTime = DateTime.MinValue;
我是新开发者,不知道如何从这里开始。 欢迎任何帮助
答案 0 :(得分:2)
Dispose方法用于释放非托管资源,换句话说,就是“.NET World”中没有的东西,比如TCP或数据库连接。
当CLR发现您的程序内存不足时,它会自动调用垃圾收集器,释放您不再使用的对象。
如果必须释放非托管资源,则只需要实现IDisposable。有关实现IDisposable的详细信息,您可以在线查找大量文章。对于instace,你正在伪造实现你的类终结器。
因此,如果问题出在播放文件的方法中,则必须首先找到导致内存增加但GC无法释放的内容。
我不知道Pcapdot.Net,但尝试找到一种方法来释放正在播放的文件,或类似的东西。也许您不需要实现IDisposable,只需添加对此方法的调用。