0

我有一个使用 Pcapdot.Net DLL 并播放 Pcap 文件的 Winform 应用程序。当我在循环中播放文件时,我可以看到应用程序内存被提升,直到发生崩溃,在堆栈跟踪中我可以看到这发生在播放文件的方法中。所以我在考虑添加 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;

我是一名新开发人员,不知道如何从这里开始。欢迎任何帮助

4

1 回答 1

2

Dispose 方法用于释放非托管资源,即“.NET World”中不存在的资源,例如 TCP 或数据库连接。

当 CLR 发现您的程序内存不足时,它会自动调用垃圾收集器,以释放您不再使用的对象。

如果必须释放非托管资源,则只需要实现 IDisposable。有关实现 IDisposable 的详细信息,您可以在网上找到很多文章。例如,您忘记了实现您的类终结器。

所以,如果问题出在播放文件的方法上,首先要找到导致内存增加而不能被GC释放的原因。

我不知道 Pcapdot.Net,但尝试找到一种方法来释放正在播放的文件,或者类似的东西。也许你不需要实现 IDisposable,只需添加对该方法的调用即可。

于 2013-05-14T16:20:47.727 回答