I have an app that uses a thread pool to ping all hosts on the local network. Each thread updates a listview with the status of that IP - alive or dead. When all the threads are done, I want to remove all the dead links from the list view.
- How can I tell when all the threads have done their job
- What is the best way to loop over the listview backwards (I assume backwards is best since the items are indexed...), removing each dead link (text in column 1 = "dead")
Thanks in advance.

How do I tell when all threads in a pool are complete
Bill Byrnes
Yarg.
I created a new thread that does cleanup - the function looks like this:
private void Cleanup(object key){
for (int i = listView1.Items.Count - 1; i > -1; i--)_ewh.WaitOne();
{
if (_InvokeGetListView(i, 1) == "Dead")
_InvokeRemoveListItem(i);
}
}
At the end of all of my other threads I do this check in the finally statement:
finally{
if (tc == 0 && ats)tc--;
_ewh.Set();
}
I got the cross-threading error again, so I hacked those invoke functions. This sure would be a lot easier if I could run the cleanup from the main thread. As it is, the invoke function is returning an error - return type must be able to be converted to a string or something like that. I have no idea what to do about this because I don't understand the invoke/delegate thing.
private delegate string _InvokeGetListViewDelegate(int _row, int _column); private string _InvokeGetListView(int _row, int _column){
// If it's coming from another thread, Invoke _InvokeToListView trough the _InvokeToListViewDelegate and end this thing. if (this.InvokeRequired) { this.Invoke(new _InvokeGetListViewDelegate(_InvokeGetListView), _row, _column); return; } // If it passed that last test, then it's either coming from the form's own thread or invoked from another thread, and the stuff can be edited safely. return listView1.Items[_row].SubItems[_column].Text;}
private delegate void _InvokeRemoveListItemDelegate(int _row); private void _InvokeRemoveListItem(int _row){
// If it's coming from another thread, Invoke _InvokeToListView trough the _InvokeToListViewDelegate and end this thing. if (this.InvokeRequired) { this.Invoke(new _InvokeRemoveListItemDelegate(_InvokeRemoveListItem), _row); return; } // If it passed that last test, then it's either coming from the form's own thread or invoked from another thread, and the stuff can be edited safely.listView1.Items[_row].Remove();
}
Oleg_Ivanov
TANWare
At the beginning of the threads that need to be counted, add 1 to this integer.
At the end of those threads, remove 1, and if it's 0 after removing AND all threads have started (create a bool for this too, to flag that every needed thread is started), then all threads have done their work (and set the all-started bool to false).
Backwards
for (int i = listView1.Items.Count -1; i > -1; i--)
{
// listView1.Items[i].
}
stupots
Put one of these in your code somewhere:
System.Threading.EventWaitHandle _ewh = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset);
The thread that needs to wait (don't do this on UI thread) till everything's done does this:
_ewh.WaitOne();
The last thread (the one where all threads started and the integer is 0) does:
_ewh.Set();
to let the waiting thread continue it's work.
That's one of the clean ways to let a thread wait for another thread. :)
Romek
if (this.InvokeRequired) { return this.Invoke(new _InvokeGetListViewDelegate(_InvokeGetListView), _row, _column); /* and remove return here (which returned something (null) to ignore the stuff below) */}
i'm not sure if that really works, try playing around with the invoke thing a bit, cause you need to get the parameter trough the invoke that is done up there ;)
but i don't think invoke is needed when just reading some text.
M. Leary
Would it make the most sense to have that cleanup process run in the last thread then I thought it would be cleaner to have it run from the main thread so I wouldn't have to figure out that invoke/delegate nonsense for the delete :) can I create a do -while integer > 0 sleep function in the main thread, then perform the cleanup after it exits this loop Is there a more elegant way