我有一个客户端/服务器系统,客户端在该系统上充当服务器的从属。我的一个表格有一个listview
由客户端上运行的进程填充的表格。同样的表格只能打开一次,因为第二次出现异常:InvalidOperationException
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
表单构造函数:
public ProcessesForm(NetworkStream _stream)
{
InitializeComponent();
networkStream = _stream;
//event on which the process list will be processed
Server.OnProcessListingReceived += Server_OnProcessListingReceived;
//request client for process list
GetProcesses();
this.ActiveControl = textBox1;
}
事件处理程序:
private void Server_OnProcessListingReceived(object sender,
EventArgs.ProcessesEventArgs e)
{
//exception is thrown here
listView1.Invoke(new EventHandler(delegate { listView1.Items.Clear(); }));
processes = new List<ProcessesEventArgs.Process>(e.Processes);
foreach (var item in e.Processes)
{
ListViewItem lvi = new ListViewItem(item.Id);
lvi.SubItems.Add(item.Name);
lvi.SubItems.Add((Convert.ToInt64(item.Memory) / 1024).ToString());
listView1.Invoke(new EventHandler(delegate { listView1.Items.Add(lvi); }));
}
}
我正在调用 ,listview
因为接收到的列表处理是在相应的客户端线程上完成的。
正如我在帖子开头所说的那样,在第一次打开表单时,一切正常。
我已经尝试过的:
- 手动创建句柄
- 在表单关闭时取消分配
OnProcessListingReceived
事件。 - 其他没有用的东西,我真的不记得了。
这个问题的原因可能是什么?
编辑:
正如汉斯帕桑特所说,问题可能是thread race
,但如果是这样的话,不应该lock
解决问题吗?我尝试实现锁定,但没有奏效:
lock(listView1)
{
listView1.Invoke(new EventHandler(delegate { listView1.Items.Clear(); }));
}