首页 新闻 会员 周边

为什么同一个函数方法(将datatable数据表显示在dgv控件上),放在串口DataReceived事件方法上会报错主窗体有引用空,放在button按钮事件上不会报错。

0
悬赏园豆:80 [已解决问题] 解决于 2020-03-09 17:02

报错异常:nullreferenceexception
infinite recursion during resource lookup within mscorlib.this may be a bug in mscorlib,or potentially in certain extensibility points such as assembly resolver events or cultureinfo names.resource name:Arg_nullreferenceexception

😀明笔记的主页 😀明笔记 | 初学一级 | 园豆:13
提问于:2020-03-09 15:41
< >
分享
最佳答案
1

这个应该你把方法写在哪没有关系,姑且不看你的这个异常信息,很少见,没碰到过。
1 你看一下,打断点在这个数据接收事件,看看哪个对象为空,找到空对象看看对比一下button事件看看是什么时候赋值的
2 真如异常信息一样是库的bug,你就改方式被,哪个对象你看是空的,你就先实例化成私有字段再传进去被

收获园豆:80
猝不及防 | 老鸟四级 |园豆:2781 | 2020-03-09 16:12

调用是一模一样的,至少调用的方式不一样。一个是串口接收数据后触发,另外一个是按钮点击直接触发。前者报错,后者没问题

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 16:16

@😀明笔记: 你贴一下全部的异常信息,看一下调用堆栈

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:22

@猝不及防:
未处理System.NullReferenceException
HResult=-2147467261
Message=未将对象引用设置到对象的实例。
Source=System.Windows.Forms
StackTrace:
在 System.Windows.Forms.DataGridViewTextBoxCell.PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, Boolean computeContentBounds, Boolean computeErrorIconBounds, Boolean paint)
在 System.Windows.Forms.DataGridViewTextBoxCell.Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object value, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
在 System.Windows.Forms.DataGridViewCell.PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
在 System.Windows.Forms.DataGridViewRow.PaintCells(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)
在 System.Windows.Forms.DataGridViewRow.Paint(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)
在 System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)
在 System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded)
在 System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
在 System.Windows.Forms.Control.WmPaint(Message& m)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.DataGridView.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
InnerException:

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 16:23

@😀明笔记: 我刚查了一下,这个事件触发不是在ui线程,你需要委托去修改ui,但是给dgv赋值不确定需不需要一定是ui线程,https://www.cnblogs.com/vuciao/p/10881312.html

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:25

@猝不及防: 如果可以的话。可以教一下我怎么看这个调用堆栈的吗?

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 16:25

@😀明笔记: 从下往上,由浅层次到深层次,
比如触发A=System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
这个B=System.Windows.Forms.DataGridView.PaintGrid就是A内部的方法
System.Windows.Forms.DataGridView.PaintRows就是B内部的方法

DataGridView绘制-->Grid(格子)绘制-->(行绘制)Row绘制-->....

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:33

@猝不及防: 看这个堆栈调用,你是怎么想到委托这个问题的???我很好奇。看到空引用异常,我根本想不到

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 16:37

看一下定义:
DataReceived事件:在接收到了ReceivedBytesThreshold设置的字符个数或接收到了文件结束字符并将其放入了输入缓冲区时被触发。

会不会是你的DataReceived事件触发次数太多,导致界面没有刷完就又触发了?

因为C# serialport 提供的DataReceived,当触发了事件后就会调用事件函数,不论之前那个有没有处理完,所以每次调用事件函数时一定要保证快速的执行完,防止下次的触发事件在上一次还没执行完就又开始了。所以最后改为每次只检查串口接收缓冲区中存储的数据量,不在那里等待,直到满足数量要求后再取出来。
————————————————
版权声明:本文为CSDN博主「Hilaph」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Hilaph/article/details/101672672

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:38

@😀明笔记:
跟控件相关问题..第一就是非ui线程不能给ui线程赋值
你这有串口,可能涉及到数据收没收完(结束符,延迟事件),非托管资源要自己关闭串口,是否被占用等

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:41

@猝不及防: 很奇怪!!我之前一直都是用DataReceived事件上写,改变ui界面上的控件颜色。没有用到委托也可以运行,不会报错。怎么这个方法就必须要用到委托才行呢??

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 16:47

@😀明笔记:
老实说我也不确定内部是咋回事,封装的太好了,单说这个DataReceived是自己新开的线程我都不确定那个博客说的对,
事实上我觉得你新建个thread在里面改变控件颜色甚至都不报错,但是如果你如果增删控件是一定会报错的

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:50

@😀明笔记:
一般来说不太会在DataReceived里面去改变控件
除非你是想设备数据去主动驱动界面,界面随着数据主动的变化
一般的做法就跟你的按钮一样,点击按钮,串口获取数据,验证完整后改变界面

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:54

@猝不及防: 所以你是怎么从堆栈调用中,一眼就看到是委托的问题的?程序可以正常运行了哦!!

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 16:54

@😀明笔记: 看不出来,百度的

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 16:56

@猝不及防: 感谢你的耐心回答!受益匪浅~

😀明笔记 | 园豆:13 (初学一级) | 2020-03-09 17:02

@😀明笔记: 当年也是一群人帮助无知的我,希望你继续做下去,C#永不为奴~~!

猝不及防 | 园豆:2781 (老鸟四级) | 2020-03-09 17:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册