不应该出现的跨线程操作异常
本文关键字:线程 操作 异常 不应该 | 更新日期: 2023-09-27 18:11:36
当我的方法被FileSystemWatcher事件调用时,我在VS2013, WinForms,调试模式上有一个奇怪的Cross-thread operation exception
。
异常出现在flowLayoutPanel.ResumeLayout();
上。
代码是:
public void AddStrategyIcon(StrategyIcon[] icons)
{
if (flowLayoutPanel.InvokeRequired)
flowLayoutPanel.Invoke(new Action<StrategyIcon[]>(AddStrategyIcon),
new object[] {icons});
else
{
flowLayoutPanel.SuspendLayout();
flowLayoutPanel.Controls.AddRange(icons);
flowLayoutPanel.ResumeLayout(); // <- Cross-thread op. not valid ...
}
}
知道为什么会抛出异常以及如何修复它吗?
如果flowLayoutPanel
是在UI线程以外的线程上创建的,那么flowLayoutPanel.InvokeRequired
将报告如果在相同的非UI线程上调用则不需要调用。
然而,当你调用ResumeLayout()
,最终调用函数上的包含控件谁住在UI线程,并引发错误。
找到你调用flowLayoutPanel = new FlowLayoutPanel()
的地方,看看它是否被一个不是主UI线程的线程调用。
在方法参数中发现问题。StrategyIcon
是一个带有自定义绘图的用户控件。
它崩溃在:
flowLayoutPanel.Invoke(new Action<StrategyIcon[]>(AddStrategyIcon),
new object[] {icons});
通过将参数更改为DTO(数据传输对象)并将UserControls的实际创建移动到视图来修复此问题:
工作代码:public void AddStrategyIcon(StrategyIconDto[] dtoList)
{
if (flowLayoutPanel.InvokeRequired)
flowLayoutPanel.Invoke(new Action<StrategyIconDto[]>(AddStrategyIcon),
new object[] {dtoList});
else
{
var controls = new List<Control>();
foreach (StrategyIconDto dto in dtoList)
controls.Add((Control) new StrategyIcon(dto));
flowLayoutPanel.SuspendLayout();
flowLayoutPanel.Controls.AddRange(controls.ToArray());
flowLayoutPanel.ResumeLayout();
}
}