Should I worry about releasing resources in this case? - c#

Let's say I have a class Collection which holds a list of Items.
public class Collection
{
private List<Item> MyList;
//...
}
I have several instances of this Collection class which all have different MyLists but share some Items.
For example: There are 10 Items, Collection1 references Items 1-4, Collection2 has Items 2-8 and Collection3 4,7,8 and 10 on its List.
I implemented this as follows: I have one global List which holds any Items available. Before I create a new Collection I check if there are already Items I need in this list -- if not I create the Item and add it to the global List (and to the Collection of course).
The problem I see is that those Items will never be released - even if all Collections are gone, the memory they consume is still not freed because the global list still references them.
Is this something I need to worry about? If so, what should I do? I thought of adding a counter to the global list to see when an Item is not needed anymore and remove its reference.
Edit:
It is in fact a design problem, I think. I will discard the idea of a global list and instead loop through all Collections and see if they have the needed Item already.

If the global list needs references to the items then you can't realistically free them. Do you actually need references to the items in the global list? When should you logically be able to remove items from the global list?
You could consider using weak references in the global list, and periodically pruning the WeakReference values themselves if their referents have been collected.

It looks like a bit of a design problem, do you really need the global list?
Apart from weakreferences that Jon mentions, you could also periodically rebuild the global list (for example after deleting a collection) or only build it dynamically when you need it and release it again.
You'll have to decide which method is most appropriate, we don't have enough context here.

Related

Complication in adding and removing object to a large collection in c#

Couple of days ago, I faced a question that I have a collection which is having historical data or very large amount of objects. This collection is exposed to so many threads or clients, So, people might be iterating over it and some might be adding to it and some might be removing to this collection while iteration. So, modification might throw "collection changed exception" in c#.
Now, I need to design a data structure or a collection in c#
which fulfills following challenges :
You can't copy the collection to different object as Collection is very large,
So copying it would cause us lot of memory wastage.
while any user adds to collection while iterating the collection, new object should be added in the collection and should not throw any exception and should also be read in the end of the iteration as well as.
But in case user removes any item from the collection, then it should throw the exception.
Adding, removing and iterating should be thread safe. No race condition should be there.
If you really insist to use a collection and not a database. None of the regular .NET lists will be a good option. In that case you could create your own list type that is optimised for your situation.
It depends on other details (can you work with paging, do you need to acces items by index etc) what technics you could use.
An idea could be that you create one mutable list and only when it change, you create one immutable copy. All the clients use the last immutable copy.

timing how long an element has been in a list

What would be the easiest way to track how long an element has been part of a list? For instance, I would like to pop an element from a list after it has been added for 2 minutes.
Would I have to create two lists, one holding the actual element and the other the time that element was added to the list? Then checking the "time" list in order to know when it has reached two minutes?
I have a feeling theres a much simpler and efficient method to do this but I cannot think of it at the moment...
If you want to have the minimum amount of code to write, you can have a look at the MemoryCache class, which implements an expiration policy.
Using the CacheItemPolicy you can even have a callback method executed when the item is removed after expiration.
Rather than storing the elements in the lists directly, you could use a wrapper class which included the element and its storage time, then store instances of the wrapper class instead.
You would probably want to use a queue rather than a list; you will be removing items from the front a lot, which is far more efficient with a queue than with a list.
How often you check the queue is something you'd need to decide on. You could possibly use a separate thread to check every so often, in which case you'd probably want to use a ConcurrentQueue<T>

Lazy list clone

I have a List with a large amount of elements in it. I need to create a copy of this list to perform operations on it without altering the original list. However, the operations typically only access a small proportion of the elements of the list, and so it is inefficient to copy the entire thing when most of it will go unused. Is there a simple way to create an object which is a clone of a list, but only clones elements when they are accessed? I have looked into the Lazy<T> class, which seems to be what I want, but I don't know how to apply it in this situation.
I want to be able to do something like this:
LazyListCopy<SomeType> lazyCopy = LazyListCopy.Copy(myList); // No elements have been copied at this point
DoSomethingWith(lazyCopy[34]); // 35th element has now been copied
And this:
foreach(SomeType listElement in LazyCopy.Copy(myOtherList))
{
if (!Check(listElement)) // Object corresponding to listElement has been cloned
break;
}
I don't mind if the solution isn't generic enough to handle Lists of any type; I would be fine with it being specific to one or two classes I've created.
Preferably this would be a deep copy rather than a shallow copy, but a shallow copy would still be useful, and I would appreciate examples of that if it is shorter/simpler too.
Sounds like you want to end up with your original list plus a sparse collection of overrides.
Why not create a dictionary for the overrides, keyed on the index into the original list? You can then manually add values from your original list as they are needed.
You could wrap this functionality up into a class that wraps IList<T> if it's something you're going to use often.

Would setting a collection to null after assigning it to an itemssource clear up resources?

I was doing some performance optimization inside my app and there were a lot of places where I'm assigning a collection to the itemssource property of a listbox. When I assign the collection to the listbox is the original collection disposed from memory. If not, by setting it to null will it mark the collection for garbage collection?
For example:
void myWebServiceCompleted(object sender, List<Item> itemList)
{
ItemListBox.ItemsSource = itemList;
//Would setting itemList = null clear up resources?
}
I was just concerned because this type of assignment is made in multiple places in the app and if the above is true that means twice the memory.
No.
the ListBox holds a reference to your original list, so it is not garbage collected.
If for whatever reason you wanted the original list to get collected, you could manually add ListItems to the ListBox.
In this case the original list could get collected as long as there were no other references.
I guess this would be useful if each of the items in your collection was resource-heavy, and the listbox only needed to know a couple of fields (name and id for example)
No, it would not. itemList is a reference type. It's not duplicated like you think it is. Instead, you just have multiple references to it. It's like receiving multiple letters in the mail with the same address on them. It doesn't mean the house with that address is duplicated, just that there are multiple addresses referring to the same house.
As long as one rooted object still refers to your collection, it will not be freed by the garbage collector. Setting itemList to null has no effect on the total space consumed by this collection.
I was just concerned because this type of assignment is made in multiple places in the app and that means twice the memory.
It does not mean that. I strongly encourage you to drop everything you're doing and read about reference types until you understand this incredibly important point.
I now understand why Joel Spolsky thinks every programmer should learn C.

.NET: Observable + Sortable CollectionView on a Set (custom HasSet<>)

I look for a way to observe a collection for changes, without using indices. I know when items are added and removed from the source collection, but the collection is not using indices (it's a custom kind of hashset with notification on add/remove). Items are being populated to the list in a undeterministic order and using indices wouldnt make much sense, so I'm trying to avoid it completely. But Im still going to bind this list to a view, so there will be some ordering of the items eventually. My goal is to have all the ordering in a collectionview.
The question is if there is a way to make a collectionview on a index-less source collection and still get the UI to respond to items being removed and added effectively without having to rebuild the list everytime. I'm not sure if I make any sense here. My goal is to get rid of indices but still benefit from collectionchanged-events and collectionview-ordering. Possible?
UPDATE
I've tried to implement a custom ICollectionView such as SetCollectionView(HashSet set) but it won't work for some reason. Not yet anyway.
Another option could perhaps be to implement a custom ReadOnlyObservableCollection-wrapper with some custom ordering on the GetEnumerator. I haven't tested it yet. I would have to sort the list according to the choosen ordering before extracting the index for the NotifyCollectionChanged-event but that should work.
You can use the ObservableHashSet class.
See the question here
How can I make an Observable Hashset in C#?
or go directly to the code here:
http://geoffcox.bellacode.com/2011/12/09/observablehashset/
You need to have an index somewhere, because all of the UI binding plumbing is index-based. You can layer an indexed list over your existing hashset, but it's going to be slow (I can't provide a formal proof, but my gut tells me it would be quite awful, something like O(n)). If you want a quick base collection that you can layer re-ordered UI lists on top of, you might want to look into a balanced sorted tree, rather than a hashset.

Categories