M
Martin Maat
Hi,
I have the strangest thing...
I am porting a C# .NET framework 1.1 application to framework 2.0. I got
slapped around by the new framework on my unsafe use of threading, requring
me to marshall all events coming from worker threads to the main UI thread
before calling into controls. Fair enough, more power to my app, it should
be more robust now and I've become a regular delegate-master. So far so
good.
There is one method though that still throws an exception even though I
fixed the threading issue. And it is weird. Very, very weird.
It is about a ListView. I remove the first item after adding one to the
collection (is it a list of log entries that is not supposed to grow
indefinately).
// trim list (both entries and view)
while (entries.Count > entries.RollOverCount)
{
listViewActivityLog.Items.RemoveAt(0); // exception is thrown here
entries.RemoveAt(0);
}
The Tag properties hold references to log entry objects. Sometimes it works
a couple of times before the exception is thrown, it is a
NullReferenceException and the call stack shows that
listViewActivityLog.Items.RemoveAt actually succeeds and that the failure
occurs in a method deeper in the call stack named "UpdateSavedCheckedItems".
The debugger also suggests that the item was indeed removed at the time the
exception is thrown.
- The thread is definitely the main UI thread that created the ListView;
- the list definitely contains plenty of items (256 or more, I set
RollOverCount at 256), the item is not null when it is removed.
With framework 1.1 the method was called on the worker thread and I locked
listViewActivity to make it thread-safe (in my mind). I removed the lock
after I had marshalled the thread in the ported code because there seemed to
be no point any longer to perform the lock. Nonetheless I tried it with
locking listViewActivity again just to make sure that had nothing to do with
it. It made no difference.
Any ideas? Workarounds?
This is the stack trace:
at System.Windows.Forms.ListView.UpdateSavedCheckedItems(ListViewItem
item, Boolean addItem)\r\n
at
System.Windows.Forms.ListView.ListViewNativeItemCollection.RemoveAt(Int32
index)\r\n
at System.Windows.Forms.ListView.ListViewItemCollection.RemoveAt(Int32
index)\r\n
The above is the inner exception, the outer exception is a
TargetInvocationException. If I don't put a breakpoint on the offending
line, the debugger will stop at
base.WndProc(ref m);
in WndProc
Thanks for thinking with me.
Regards, Martin.
I have the strangest thing...
I am porting a C# .NET framework 1.1 application to framework 2.0. I got
slapped around by the new framework on my unsafe use of threading, requring
me to marshall all events coming from worker threads to the main UI thread
before calling into controls. Fair enough, more power to my app, it should
be more robust now and I've become a regular delegate-master. So far so
good.
There is one method though that still throws an exception even though I
fixed the threading issue. And it is weird. Very, very weird.
It is about a ListView. I remove the first item after adding one to the
collection (is it a list of log entries that is not supposed to grow
indefinately).
// trim list (both entries and view)
while (entries.Count > entries.RollOverCount)
{
listViewActivityLog.Items.RemoveAt(0); // exception is thrown here
entries.RemoveAt(0);
}
The Tag properties hold references to log entry objects. Sometimes it works
a couple of times before the exception is thrown, it is a
NullReferenceException and the call stack shows that
listViewActivityLog.Items.RemoveAt actually succeeds and that the failure
occurs in a method deeper in the call stack named "UpdateSavedCheckedItems".
The debugger also suggests that the item was indeed removed at the time the
exception is thrown.
- The thread is definitely the main UI thread that created the ListView;
- the list definitely contains plenty of items (256 or more, I set
RollOverCount at 256), the item is not null when it is removed.
With framework 1.1 the method was called on the worker thread and I locked
listViewActivity to make it thread-safe (in my mind). I removed the lock
after I had marshalled the thread in the ported code because there seemed to
be no point any longer to perform the lock. Nonetheless I tried it with
locking listViewActivity again just to make sure that had nothing to do with
it. It made no difference.
Any ideas? Workarounds?
This is the stack trace:
at System.Windows.Forms.ListView.UpdateSavedCheckedItems(ListViewItem
item, Boolean addItem)\r\n
at
System.Windows.Forms.ListView.ListViewNativeItemCollection.RemoveAt(Int32
index)\r\n
at System.Windows.Forms.ListView.ListViewItemCollection.RemoveAt(Int32
index)\r\n
The above is the inner exception, the outer exception is a
TargetInvocationException. If I don't put a breakpoint on the offending
line, the debugger will stop at
base.WndProc(ref m);
in WndProc
Thanks for thinking with me.
Regards, Martin.