I am trying to store a type of System.Collection.Queue. The queue will only contain strings. The issue is that when I attempt to use it, it is always Null.
Settings.Default.CorrectionsDescription.Enqueue(textString);
I get the following error.
Object reference not set to an instance of an object.
I have gotten StringCollection to work fine, but I need a FIFO queue.
How do you initialize the queue, in the Settings or through code? When I tried, it gave the error that it is read only.
Settings usually only store data in very simple objects or collections (xml-serializable, even Dictionary<TKey, TValue> already causes problem!).
Queue has special semantics and is not very suitable for data storage.
I suggest to use List<string> or StringCollection to store settings and create Queue on start of your application based on that collection.
Saving is the same but in reverse order - create List from your Queue, put it into Settings class and save.
Update:
Standard settings mechanism uses XML serialization for object persistence.
Object implementing IEnumerable<T> must also have method Add(T value) to be xml-serializable. Queue<T> doesn't have such method so can't be successfully deserialized.
MSDN:
XmlSerializer can process classes that implement IEnumerable or ICollection differently if they meet certain requirements. A class that implements IEnumerable must implement a public Add method that takes a single parameter
I have always just used:
if (Settings.Default.CorrectionsDescription == null)
{
Settings.Default.CorrectionsDescription = new Queue();
}
at the program startup, but I would like to know of a better way as well.
Related
I'm currently trying to implement Fluxor for my Blazor WASM app and all the instructions/tutorials I found recommended something like this example for the Store:
public record AppStore {
int ClickCounter,
bool IsLoading,
WeatherForecast[]? Forecasts
}
and then only talk about initial state and updates only happen to the bool and the int while the array is only ever replaced outright. I.e. the examples always fetch the complete data from the server, e.g. a 100 entries.
Now, here's my question: How do I properly deal with the array in my reducer when I have already 100 entries in there and only want do add/update/delete one? Is that even a good idea in the first place?
The best thing to do is to use ImmutableList<T> or ImmutableArray<T> instead, as this class is optimised for the purpose of returning a new instance that includes old data but without having to copy the elements.
I've recently released a new library called Reducible that helps to create complex state reducers. It results in fewer updates (e.g. a new parent object isn't created if an item in the list is not replaced).
https://github.com/mrpmorris/Reducible/blob/master/README.md
In my system, I need my clients to be able to get a List of objects, representative of the service states/context.
Say you have the following action done by a given client to retrieve the context:
List<someObjects> aList = GetListOfObjects();
Now the client is able to retrieve aList, but it can also modify this list before sending it back through the channel, which I would like to prevent (as it would not be representative of the system anymore). Therefore, the client should not be able to do:
aList.RemoveAt(1); // Should not be possible to remove object from this list
SetListOfObjects(aList);
I thought I could create a readonly "aList" class, but I still want to be able to modify the objects' properties, so I don't thing it is the right thing to do.
One idea is to actually create a class, where all objects from the aList would be properties instead. That way, the class would impose a structure that could not be modified by the client. However, the system's context may vary (depending on the hardware being used), meaning this class would need to be dynamically created.
I however do not want to lose the type safety and hence would rather not use the dynamic or expando Objects.
Maybe using something of the sort is a good idea here, see answer from danijels. But I am not sure the type safety would be preserved by doing so.
I have a cache service that holds multiple Price objects which are updated as new price deltas arrive, sometimes multiple times a second.
Each object holds it's various prices in a collection assigned to an ID. If someone subscribes to a particular price I need to serialize the latest price object into JSON each time a new price arrives in order to send it over RMQ. The problem I am having is that in some cases I receive the following error message while serializing because a new price has arrived and updated the collection on the object during the serialization of the previous.
"Collection was modified; enumeration operation may not execute."
I've tried various ways of serializing the object (it needs to be as fast as possible) but I still get the same issue.
What would be the best and most efficient way of solving this so I can serialize even if the object changes.
The simplified objects are:
//This is the collection on an object that holds the prices which are being updated
public ConcurrentDictionary<Id, Prices> Asset{ get; set; }
//Class that holds the ever updating prices
[Serializable]
public class Prices
{
public Prices()
{
Prices1 = new List<PriceVolume>();
Prices2 = new List<PriceVolume>();
}
}
thanks in advance!
Instead of serializing the actual object you pull from the concurrent dictionary you should create a deep copy of it and serialize the copy. unfortunately you will still have to put the code to get the copy inside a mutex. The ConcurrentDic is only protecting you from having an item changed or deleted while you are retrieving it, it does not protect the object from manipulation after you have retrieved your reference to it.
You could probably benefit from locking the element while you are serializing it.
Locking prevents other threads from modifying the element while you are inside the lock.
This will make the operations trying to change the prices wait until you are done serializing it to modify them.
[Serializable]
public class Prices
{
public string Serialize()
{
lock (this)
{
// logic for serilization here
}
}
}
Just a thought, but how about looking into Serialization Callbacks (some refer to this as Serialization Hooks) and Implementing the ISerializable Interface. You seem to need more fine-grained control over the serialization of your object. Have a look at this link:
Custom Serialization
Look at the following
OnDeserializingAttribute (Before deserialization)
OnDeserializedAttribute (After deserialization)
OnSerializingAttribute (Before serialization)
OnSerializedAttribute (After serialization)
Also have a look at this link:
Version Tolerant Serialization
You can consider if the object warrants the use of the OptionalFieldAttribute or NonSerializedAttribute on certain fields to control if they need to be serialized or optionally serialized. Just be wary of the use of the NonSerializedAttribute. Have a look at the best practices mentioned in the article (reproduced here for reference):
To ensure proper versioning behavior, follow these rules when modifying a type from version to version:
Never remove a serialized field
Never apply the NonSerializedAttribute attribute to a field if the attribute was not applied to the field in the previous version
Never change the name or the type of a serialized field
When adding a new serialized field, apply the OptionalFieldAttribute attribute
When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute
For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable
To ensure that a type will be compatible with future serialization engines, follow these guidelines:
Always set the VersionAdded property on the OptionalFieldAttribute attribute correctly
Avoid branched versioning
For the purpose of XML serialisation I had to disband a Dictionary collection I was using. I wrote a very straightforward alternative which consists of 2 classes:
NameValueItem: contains Name (Key) and Value
NameValueCollection: derived from CollectionBase and maintains a collection of NameValueItem objects.
I've included some standard methods to help maintain the collection (Add, Contains and Remove). So just like most Dictionary types, the Name (or Key) is unique:
public bool Contains(NameValueItem item)
{
foreach (NameValueItem lItem in List)
if(lItem.Name.Equals(item.Name))
return true;
return false;
}
Add uses this Contains method to determine whether to include a given item into the collection:
public void Add(NameValueItem item)
{
if (!Contains(item))
List.Add(item);
}
As bog standard, straightforward and easy as this code appears it's proving to be a little sluggish. Is there anything that can be done to improve the performance of this? Or alternatives I could use?
I was considering creating a NameValueHashSet, which is derived from HashSet.
Optional...:
I had a question which I was going to ask in a separate thread, but I'll leave it up to you as to whether you'd like to address it or not.
I wanted to add 2 properties to the NameValueCollection, Names and Values, which return a List of strings from the Collection of NameValueItem objects. Instead I built them into methods GetNames() and GetValues(), as I have to build the collection (i.e. create a List (names/values), iterate over collection adding names/value to List and return List).
Is this a better alternative? In terms of good coding practise, performance, etc.? As my thoughts regarding properties has always been to have it as stripped back as possible, that only references, arithmetic, etc. should exist, with no layers of processes. If that is the case, then it should be built into a method. Thoughts?
Perhaps you shouldn't try to rebuild what the framework already provides? Your implementation of a dictionary is going to perform poorly as it does not scale. The built in Dictionary<TKey, TValue> has O(1) access performance and for most insert and delete operations (unless there are collisions or the internal storage must be expanded).
You can extend the existing dictionary to provide XML serialization support; see this question and answers: Serialize Class containing Dictionary member
As for your second question - Dictionary already provides methods for getting an IEnumerable of the keys and values. This enumerates the keys and/or values as requested by the caller; that is delayed execution and is likely the preferred method over building a full List every time (which requires iterating through all the elements in the dictionary). If the caller wants a list then they just do dictionary.Values.ToList().
I have a class MyClass containing a private List<MySecondClass> myList. The list is exposed through a getter as follows:
public IEnumerable<MySecondClass> MyList
{
get { return myList.Select(a => a); }
}
The list is modified through public AddItem(MySecondClass itemToAdd) and ClearItems() methods. I believe that this is a properly encapsulated list.
The problem lies in that I need to pass an object of type MyClass (containing myList) via SOAP to a web service, which fills myList (using the AddItem() method), and then returns the object.
However, when the webmethod returns the class, after serialization myList is empty. I am suspecting this is because I do not have a setter for myList, which is causing the list not to be set during serialization.
Is this a good assumption, or am I way off? If the problem is what I think it is, is there a way to allow for the list to be successfully passed from the webmethod without breaking encapsulation (I do not want to expose a generic list)?
Without trying this directly myself, I believe that you could definitely be correct.
serialization in .NET makes utilizing read only properties a fun circus.because the .net default serialization process requires a setter property in order to "deserialize" the object. Without a setter property the serialization piece will still work allowing you to serialize to a drive or across the network. But, it is the deserialization process that will fail which could definitely be why your collection is empty. Im just amazed it doesn't error out to be honest.
Have you tried to add a simple setter just to verify that this is in fact the issue just so that we know with 100% certainty that this is the problem before working to solve it.
While I never really solved the initial problem, what I did do to get it working was simplify the data that was being passed to the web method. Instead of passing an entire object to the web method, I instead passed a unique identifier. The webmethod then returns the list I need, and I handle actually adding the items in this list to the object client-side.
The XML Serializer used by ASMX services only serializes public read/write properties.