动态加载多个usercontrol绘图数据错乱

fffgggfff4 2018-04-24 10:30:21
实际程序描述起来比较复杂,且由于连接了板卡,单独上传代码也无法调试,所以我把问题简化提炼了一下:

1,软件(使用WPF框架编写)启动后主界面动态加载三个usercontrol,即,将new usercontrol[k](k=3)依次add到Grid里;

2,系统从一块板卡接收报文数据(TCP异步)每次3000字节,构建成int[i,j](i=3,j=1000),比对i和k,将1000字节发送到对应的usercontrol,通过其绘制柱状图;

3,由于这三个1000字节的数列大小有明显差异,因此通过谱图的幅值很容易看出,绘图的数据对应出现了错乱,如usercontrol[0]的绘图控件绘制了数组int[2,]对应数据的柱状图。

大致思路如图


运行效果如图,当前时刻,三个usercontrol加载着同一个数组的数据,但它们本该加载各自对应的不同数组数据
给人一种直观的感觉是,new的三个usercontrol中的数据是共享/互通的。


调试时,有着TCP异步数据错乱一个很常见的特征,就是单步断点调试时数据无误,连续运行则出错。但目前调试只用到一块板卡,接受的只有一种报文且间隔长达1秒,怀疑不是异步的问题。所以请教下各位高手问题可能出在哪。
...全文
2721 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2018-04-24
  • 打赏
  • 举报
回复
我认为问题出在左边第一个方框 既然数据最终是以3个图表展示,显然传入的数据是由三个分量(或可拆解成3个分量)组成的 而对于 a、b、c 3个分量 的检出,就是问题的关键所在 如果设备是按 a b c a b c a b c.....这样发出的,而你却误以为是 a a a ... b b b ... c c c... 这样的顺序(或者反之),这样势必造成数据的混乱 虽然一般会理解为 a b c a b c a b c.....(因为不需要缓存),但凡事都是有例外的,需要认真阅读板卡的说明,才能确认
fffgggfff4 2018-04-24
  • 打赏
  • 举报
回复
引用 3 楼 xuzuning 的回复:
你应该用3个独立的数组分别保存3组数据,这样也便于数据绑定

现在大概确定了问题的位置,但还不知道原因和解决办法
绘图逻辑如图所示

我现在切断了其他两个usercontrol的后续逻辑,也就是说只有第一个usercontrol会进行数组重新装填并绘图,但最终,它的MatrixNew数组及谱图数据依然被第三个usercontrol的旧数组MatrixOld污染。。。
绘图逻辑用到了Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() =>}));不知道是否是问题原因
很无语,按说usercontrol的MatrixNew只有translate()这么一条赋值路径,而其他两路连translate都未执行,是怎样将自己的属性跨控件传过去的呢。。。
  • 打赏
  • 举报
回复
引用 楼主 u011928118 的回复:
接受的只有一种报文且间隔长达1秒,怀疑不是
“延时”是一种很坑爹的做法,真正靠谱的通讯程序,根本不需要任何人为加入的阻塞。
xuzuning 2018-04-24
  • 打赏
  • 举报
回复
你应该用3个独立的数组分别保存3组数据,这样也便于数据绑定
xuzuning 2018-04-24
  • 打赏
  • 举报
回复
应该是分离传入数据时出现了问题,放错了位置
  • 打赏
  • 举报
回复
没有很仔细地研究你的描述,随便说一下相关的内容: 异步操作,需要明确 copy 外部变量,例如
for(var i=0; i<10; i++)
{
    var j = i;
    proc(j);
}
这里应该以 j 为异步方法的输入参数,而不是使用 i。 另外,假设同一块数据经常“刷新”,那么应该使用版本号来控制仅保留最新数据,例如
int version =0;

void test()
{
   version++;
   var v= version; 
   异步查询(......, (callbackData)=>
   {
        if(v == version)
        {
             callbackData有效
        }
   }); 
在回调时(收到结果时),只有最新版本的数据才有效,旧的查询命令晚回来的数据应该被抛弃。
fffgggfff4 2018-04-24
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
应该是分离传入数据时出现了问题,放错了位置


引用 2 楼 sp1234 的回复:
没有很仔细地研究你的描述,随便说一下相关的内容:

异步操作,需要明确 copy 外部变量,例如
for(var i=0; i<10; i++)
{
var j = i;
proc(j);
}
这里应该以 j 为异步方法的输入参数,而不是使用 i。

另外,假设同一块数据经常“刷新”,那么应该使用版本号来控制仅保留最新数据,例如
int version =0;

void test()
{
version++;
var v= version;
异步查询(......, (callbackData)=>
{
if(v == version)
{
callbackData有效
}
});

在回调时(收到结果时),只有最新版本的数据才有效,旧的查询命令晚回来的数据应该被抛弃。


经过修改,问题暂时得到解决,把之前的图的左半部分彻底摊开来看,其实改动很简单,就是将把二维数组拆分成一维并装填的方法的执行往前提了一级,如图

问题的根源依旧没有找到,只是被新的方法暂时掩盖了。感觉可能出问题的点有TCP异步、多个UserControl的动态加载以及数组传递。
节前结贴,感谢各位的指点。
也期待一些新的思路或经验。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧