0

見つけられない迷惑なバグがあり、助けていただければ幸いです。

Wiresharkファイル(Pcapファイル)を取得してパケットを再生するアプリケーションがありPcap.Net project 、ファイルを自分のファイルに追加し、 実際にパケット呼び出しを再生するクラスをListboxクリックするだけ で、アプリケーションを次のように構築します。play buttonWiresharkFile

すべてのファイルを my に追加し、Listboxplay という名前の別のクラスをクリックした後、すべてのファイル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 つのファイルを選択し、このファイルを 2 回再生することを選択した場合、最初の反復は完璧に機能しますが、2 番目の反復では私のタイマーを止めていないのにタイマーが始まらない

4

0 に答える 0