gpt4 book ai didi

C#:图表:从收到的 UDP 数据包中放入数据的最快方法

转载 作者:行者123 更新时间:2023-11-30 12:22:45 25 4
gpt4 key购买 nike

我正在尝试编写一个简单的 UDP 到图表应用程序(适用于 Windows 窗体),它将从以太网获取原始数据,并以特定方式将其放入图表中。到目前为止,这是我所拥有的:包含两个图表的表格,一个用于接收 UDP 数据包的线程:

public void serverThread()
{
UdpClient udpClient = new UdpClient(Convert.ToInt16(tbEthPort.Text));
while (_serverWork)
{
try
{
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, Convert.ToInt16(tbEthPort.Text));
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
if (receiveBytes.Length > 0)
for (i = 0; i < receiveBytes.Length; i++)
{
bigDataIn[i] = receiveBytes[i];
}

并绘制第二张图表(以特定方式显示所有数据包内容):

if (graphicOn)
{
for (i = 0; i < 32; i++)
{
graphicData[i + (graphicStep * 32)] = bigDataIn[i * 32 + graphicChan];
}
graphicStep++;
if (graphicStep == 32) graphicStep = 0;
try
{
Invoke(new Action(() => { chartGraphic.Series["DataGraphic"].Points.DataBindXY(graphicEnum, graphicData);
}));
}
catch
{
}
}

和一个带计时器的主线程来绘制第一个图表。

private void tmrHisto_Tick(object sender, EventArgs e)
{
int[] slice = new int[32];
for (int i = 0; i < 32; i++)
slice[i] = bigDataIn[i + 32 * histogramArrayStep];

histogramArrayStep++;
if (histogramArrayStep == 32) histogramArrayStep = 0;

chartHistogram.Series["DataHistogram"].Points.Clear();
for (int i = 0; i < HISTO_XMAX; i++)
{
chartHistogram.Series["DataHistogram"].Points.AddXY(i, slice[i]);
}
}

在我的电脑和其他几台电脑上一切正常,但当我在旧电脑上启动我的应用程序时,我的应用程序开始丢失数据包。当我开始 Invoke chartGraphic 时,数据包丢失就开始了。我可以在 WireShark 中看到所有数据包(大约每秒 20 个)而没有任何损失。当计时器间隔设置为 50 毫秒而不是 150 毫秒时,我遇到了同样的问题,但我不能再增加间隔了。

所以这就是我的问题 - 我能否提高图形绘制的速度,并阻止低端 PC 上的数据包丢失。或者如何在调试期间模拟低端 PC?

最佳答案

Invoke 处于阻塞状态,因此您的接收线程将等待绘图(DataBindXY) 完成。尝试将其移到接收线程之外。

循环缓冲区看起来很快,但看起来它只保存引用。这并没有太大改善。此外,您将从 udpClient 获取新缓冲区:Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint); 循环缓冲区仅在“旧”内存被重用时才有用。

尝试并发队列将数据从接收线程传递到图形用户界面线程/计时器。确保重新绑定(bind)/绘制在并发队列的锁之外。现在您获得了接收数据报的性能。


更新:

一些代码:

返回:

private List<byte[]> datagrams = new List<byte[]>();

public void serverThread()
{
UdpClient udpClient = new UdpClient(Convert.ToInt16(tbEthPort.Text));
while (_serverWork)
{
try
{
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, Convert.ToInt16(tbEthPort.Text));
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);

// add to the queue
lock (datagrams)
datagrams.Add(receiveBytes);
}
}
}

界面:

private Timer timer = new Timer();

public void timer_Tick(object sender, EventArgs e)
{
byte[][] data;

// lock the queue as short as possible. (create a copy with ToArray())
// this way the receive thread can run again..
// this is also know as bulk processing..
lock (datagrams)
{
data = datagrams.ToArray();
datagrams.Clear();
}

// if no packets received, don't update anything
if(data.Length == 0)
return;

// process the received data (multiple datagrams)
for(byte[] item in data)
{
...
}
// Update chart
}

您可能会检查队列是否变得太大。发生这种情况时,您的队列处理速度太慢。您可以限制项目数。

关于C#:图表:从收到的 UDP 数据包中放入数据的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39532998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com