0

我有烦人的错误,我找不到,很高兴得到一些帮助。

我有一个应用程序,它使用Wireshark文件(Pcap 文件)并播放数据包,Pcap.Net project 我只需将我的文件添加到我的文件中Listbox,然后单击play button 实际播放数据包调用的类,WiresharkFile 然后我以这种方式构建我的应用程序:

将我的所有文件添加到我的文件中Listbox并单击播放Job在我的所有文件的构造函数列表中接收到的另一个类以及负责调用WiresharkFile和播放文件的此类。

这是我的Job课:

using packetPlayer;
using PcapDotNet.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PacketPlayer.classes
{
    public class Job
    {
        private decimal _loopCount;
        private int _currentFileNum;
        private bool _shouldContinue;
        public bool shouldContinue
        {
            get { return _shouldContinue; }
            set
            {
                _shouldContinue = value;
                if (!_shouldContinue)
                {
                    foreach (WiresharkFile wf in wiresharkFileList)
                    {
                        wf.setIsStop(false);
                        wf.setStopButton(false);
                    }
                }
            }
        }
        private IEnumerable<string> _source;
        private PacketDevice _selectedOutputDevice;
        private double _speed;
        private int _parallelThreads;
        private decimal _loops;
        public CancellationTokenSource _tokenSource { get; set; }
        public delegate void StatusChangedDelegate(WiresharkFile wiresharkFile);
        public event StatusChangedDelegate statusChangedEvent;

        public Job(IEnumerable<string> source, PacketDevice selectedOutputDevice, double speed, int parallelThreads, decimal loops)
        {
            _source = source;
            _selectedOutputDevice = selectedOutputDevice;
            _speed = speed;
            _parallelThreads = parallelThreads;
            _loops = loops;
            _loopCount = 0;
        }

        public void doWork()
        {
            wiresharkFileList = new List<WiresharkFile>();
            _currentFileNum = 1;
            _shouldContinue = true;
            _tokenSource = new CancellationTokenSource();
            var token = _tokenSource.Token;
            Task.Factory.StartNew(() =>
            {
                try
                {
                    Parallel.ForEach(_source,
                        new ParallelOptions
                        {
                            MaxDegreeOfParallelism = _parallelThreads //limit number of parallel threads 
                        },
                        file =>
                        {
                            if (token.IsCancellationRequested)
                                return;
                            processFile(file, _selectedOutputDevice, _speed);
                            _currentFileNum++;
                        });
                }
                catch (Exception)
                { }

            }, _tokenSource.Token).ContinueWith(
                    t =>
                    {
                        _loopCount++;
                        if (continueAnotherLoop())
                            doWork();
                        else
                            OnFinishPlayEvent();
                    }
                , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
                );
        }

        private void processFile(string file, PacketDevice selectedOutputDevice, double speed)
        {
            Capinfos fileDetails = getFileDetails(file);
            WiresharkFile wiresharkFile = new WiresharkFile();
            wiresharkFileList.Add(wiresharkFile);
            wiresharkFile.startTimerEvent += wf_startTimerEvent;
            wiresharkFile.stopTimerEvent += wf_stopTimerEvent;
            wiresharkFile.statusChangedEvent += wf_statusChangedEvent;
            FileDetailsEvent(new FileInfo(file).Name, fileDetails.packets, fileDetails.duration);
            wiresharkFile.sendBuffer(file, selectedOutputDevice, speed, fileDetails.packets);
        }

        private Capinfos getFileDetails(string file)
        {
            Capinfos details = new Capinfos();
            details.readNumberOfPackets(file);
            details.readFileDuration(file);
            return details;
        }

        private void wf_statusChangedEvent(WiresharkFile wiresharkFile)
        {
            statusChangedEvent(wiresharkFile);
        }

        public int currentFileNum
        {
            get { return _currentFileNum; }
        }

        private bool continueAnotherLoop()
        {
            if (_loopCount < _loops)
                return true;
            else
                return false;
        }
    }
}

此类StatusChangedEvent将我的当前对象传递给我的表单WiresharkFile,以更新我的所有标签(WiresharkFile 类有几个属性)

这是启动计时器并每 200 毫秒更新一次我的 GUI 的形式的事件:

Timer timerPacket;

    private void job_startTimerEvent(WiresharkFile wiresharkFile)
    {
        timerPacket.Tag = wiresharkFile;

        if (InvokeRequired)
            this.Invoke((MethodInvoker)delegate
            {
                timerPacket.Start();
            });
        else
        {
            timerPacket.Start();
        }
    }

现在一切正常,我的所有标签都更新了,但我有一个奇怪的错误:如果我选择多个文件,一切正常,但如果我选择例如 1 个文件并选择播放该文件两次,第一次迭代工作完美,但在第二次迭代中我尽管我没有停止计时器,但计时器未启动

4

0 回答 0