我有烦人的错误,我找不到,很高兴得到一些帮助。
我有一个应用程序,它使用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 个文件并选择播放该文件两次,第一次迭代工作完美,但在第二次迭代中我尽管我没有停止计时器,但计时器未启动