当我的方法被FileSystemWatcher事件调用时,VS2013,WinForms,Debug模式上有一个奇怪的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 ...
}
}
任何想法为什么抛出异常以及如何解决它?
答案 0 :(得分:0)
如果在UI线程以外的线程上创建flowLayoutPanel
,那么flowLayoutPanel.InvokeRequired
将报告如果在同一个非UI线程上调用它,则不需要调用。
然而,当你调用ResumeLayout()
时,最终调用包含在UI线程上的控件上的函数,并且会引发错误。
查找您调用flowLayoutPanel = new FlowLayoutPanel()
的位置,并查看是否在不是主UI线程的线程上调用它。
答案 1 :(得分:0)
问题出现在method参数中。 StrategyIcon
是带有自定义绘图的UserControl。
崩溃在:
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();
}
}