Пример #1
0
        public void ThreadSafeSetAndGet()
        {
            //Set up store
            if (System.IO.Directory.Exists("store"))
            {
                System.IO.Directory.Delete("store", true);
            }

            SessionID sessionId = new SessionID("FIX.4.2", "SENDERCOMP", "TARGETCOMP");

            Dictionary config = new Dictionary();

            config.SetString(SessionSettings.CONNECTION_TYPE, "initiator");
            config.SetString(SessionSettings.FILE_STORE_PATH, "store");

            SessionSettings settings = new SessionSettings();

            settings.Set(sessionId, config);
            FileStoreFactory factory = new FileStoreFactory(settings);

            FileStore store = (FileStore)factory.Create(sessionId);

            NullLog log = new NullLog();

            //Set up sessionstate
            SessionState state = new SessionState(log, 1)
            {
                MessageStore = store
            };

            Hashtable errorsTable = Hashtable.Synchronized(new Hashtable()); //used in more than 1 thread at a time
            Hashtable setTable    = new Hashtable(1000);                     //only used in 1 thread at a time
            Hashtable getTable    = new Hashtable(1000);                     //only used in 1 thread at a time

            //Synchronously populate 1000 messages
            for (int i = 1; i < 1000; i++)
            {
                string msg = "msg" + i;
                state.Set(i, msg);
                setTable[i] = msg;
            }

            //Simulate background sending of messages that populate into the store
            AutoResetEvent setEvent = new AutoResetEvent(false);

            ThreadPool.QueueUserWorkItem(delegate(object stateObject) {
                AutoResetEvent internalSetEvent = (AutoResetEvent)((object[])stateObject)[0];
                SessionState internalState      = (SessionState)((object[])stateObject)[1];
                for (int i = 1001; i < 2000; i++)
                {
                    try {
                        internalState.Set(i, "msg" + i);
                    }
                    catch (System.IO.IOException ex) {
                        errorsTable[ex.Message] = ex;
                    }
                }

                internalSetEvent.Set();
            }
                                         , new object[] { setEvent, state });

            //Simulate background reading of messages from the store - like is done in a resend request answer
            AutoResetEvent getEvent = new AutoResetEvent(false);

            ThreadPool.QueueUserWorkItem(delegate(object stateObject){
                AutoResetEvent internalGetEvent = (AutoResetEvent)((object[])stateObject)[0];
                SessionState internalState      = (SessionState)((object[])stateObject)[1];
                for (int i = 1; i < 1000; i++)
                {
                    try {
                        List <string> lst = new List <string>(1);
                        internalState.Get(i, i, lst);
                        if (lst.Count == 0)
                        {
                            getTable[i] = "nothing read";
                        }
                        else
                        {
                            getTable[i] = lst[0];
                        }
                    }
                    catch (System.IO.IOException ex) {
                        errorsTable[ex.Message] = ex;
                    }
                }

                internalGetEvent.Set();
            }
                                         , new object[] { getEvent, state });

            //wait till done and assert results
            Assert.True(setEvent.WaitOne(10000), "Get or Set hung/timed out during concurrent usage");
            Assert.True(getEvent.WaitOne(10000), "Get or Set hung/timed out during concurrent usage");
            Assert.AreEqual(setTable, getTable, "Garbled data read in concurrent set and get (like between resendrequest and send)");
            Assert.AreEqual(errorsTable.Count, 0, "IOException occured in concurrent set and get (like between resendrequest and send)");

            //Tear down filestore
            state.Dispose();
            store.Dispose();
        }