0

I have created a ConcurrentDictionary but am unsure of how to update an element of it:

        public class ModelClient : ICloneable
        {
            public Session session;
            public List<string> keys = new List<string>();
            public List<ModelOrder> orders = new List<ModelOrder>();

            public ModelClient(SessionID sessionID)
            {
                session = Session.LookupSession(sessionID);
            }

            public object Clone() { return this.MemberwiseClone(); }
        }

      public class ModelOrder : ICloneable
        {
            private string Symbol;
            private int Amount;
            private double Price;

            public ModelOrder(string Symbol, int Amount, double Price)
            {
                this.Symbol = Symbol;
                this.Amount = Amount;
                this.Price = Price;
            }

            public object Clone() { return this.MemberwiseClone(); }
        }

public ConcurrentDictionary<SessionID, ModelClient> ModelClients = new ConcurrentDictionary<SessionID, ModelClient>();

Here is where I need to update (by adding a new element to orders), it appears that I should use TryUpdate, but it looks very cumbersome and hard to read.

Could someone show me a good way please.

   public bool AddModelClientOrder(SessionID sessionID, string orderMessage)
    {
        string[] part = orderMessage.Split(' ');

        //HOW DO I BEST DO THIS?
        ModelClients[sessionID].orders.Add(new ModelOrder(part[0], int.Parse(part[1]), double.Parse(part[2])));
    }
ManInMoon
  • 6,795
  • 15
  • 70
  • 133
  • Hmm You're not updating the dictionary - you're updating the ModelClient's orders. – dcastro Jun 26 '14 at 14:59
  • Also notice that because the collection holding a ModelClient's orders (`List`) is not thread-safe, then that operation is not thread-safe either. – dcastro Jun 26 '14 at 15:01
  • @dcastro I had assumed that if the parent was thread safe, then access to its children would be also. – ManInMoon Jun 26 '14 at 15:04
  • @ManInMoon The retrieval of class using the indexer `[sessionID]` (it is not technically a "child") is thread safe, but the thread safety of anything you do with that class returned by the indexer is up to the implementer of the type of the class (`ModelClient`). – Scott Chamberlain Jun 26 '14 at 15:06
  • 1
    That's not correct. And "thread-safe" can mean lots of thing. For example, the concurrent dictionary is thread-safe in the sense that if two threads update the same key at the "same time", they won't leave the dictionary in a corrupt state and possibly leading to exceptions (which could have happened using a normal `Dictionary`). In this case, you're not updating the keys at all, you're only **retrieving** the value of a key-value entry - an instance of ModelClient. What you do with that value from then on, it's your own problem, the dictionary doesn't care about that at all. – dcastro Jun 26 '14 at 15:07
  • Can you suggest something please. Do I need to make List into some kind of concurrent as well - or is there a completely different way I should be looking at this? – ManInMoon Jun 26 '14 at 15:11
  • If an instance of `ModelClient` is gonna be shared between threads (which is what your code suggests), then one way of doing this would be to synchronize access to its internal data. Using a concurrent collection is one way. – dcastro Jun 26 '14 at 15:14
  • (Also, is this your actual code, or just something you wrote to demonstrate the issue? Because you *reeeeally* shouldn't be using public fields). – dcastro Jun 26 '14 at 15:15
  • If I stayed with the structure as it is now. Could you show me how to update the List<> using TryUpdate please. I am really confused by that. – ManInMoon Jun 26 '14 at 15:17
  • @ManInMoon I think you missed mine and Scott's point completely. The dictionary is not the problem here - the orders list is. Either a) change it to one of the concurrent collections, or b) use a `lock` to access the list. – dcastro Jun 26 '14 at 20:52

0 Answers0