I have a client/server system on which the clients behave as slaves to the server. One of my forms has a listview
which is populated by the processes running on the client. This same form can only be opened once, because on the second time I get an exception: InvalidOperationException
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
The form constructor:
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;
}
Event handler:
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); }));
}
}
I am invoking the listview
because the received list processing is done on the respective client thread.
As I stated on the beginning of the post everything works as it should on the first time the form is opened.
What I have already tried:
- Create handle manually
- Unassign the
OnProcessListingReceived
event on form close. - Other things which didn't work and I really can't recall.
What could be the cause of this problem?
EDIT:
As Hans Passant said the problem may be thread race
, but if this was the case shouldn't lock
solve the problem? I tried implementing lock, but didn't work:
lock(listView1)
{
listView1.Invoke(new EventHandler(delegate { listView1.Items.Clear(); }));
}