0

下面的程序是一个以相当快的速度接收数据的套接字程序。它在禁用 CodeFirst 部分的情况下运行良好。如果我启用它,程序开始时很好,但随后会慢慢降级到似乎没有任何东西写入 SQL EXPRESS 2012 db。我通过运行下面的 SQL 语句来检查这一点,该语句只选择 SQL Management Studio 2012 的最后五行。

有什么我做错了吗?

select * from [MarketDataEntities]
where MarketDataEntities.MarketDataEntityID not in (
    select top (
        (select count(*) from [MarketDataEntities]) - 5
    ) MarketDataEntities.MarketDataEntityID
    from  [MarketDataEntities]
)



               using (var dbTDC = new TickDataTestContext())
                {
                    var tde = new SymbolTickDataEntity { Symbol = symbol };
                    if (!dbTDC.SymbolTickDataDbSet.Any(a => a.Symbol.Equals(symbol)))
                    {
                        dbTDC.SymbolTickDataDbSet.Add(tde);
                        dbTDC.SaveChanges();
                    }

                    var mdde = new MarketDataDepthEntity();
                    dbTDC.MarketDataDepthDbSet.Add(mdde);

                    dbTDC.SaveChanges();

                    while (true)
                    {
                        //  Wait for next request from client 
                        int len = socket.Receive(zmq_buffer);
                        if (len < 1)
                        {
                            Console.WriteLine("Len < 1");

                            continue;
                        }

                        //Console.WriteLine("Got quote");

                        count++;

                        // Copy the bytes
                        byte[] bytes = new byte[len];
                        Buffer.BlockCopy(zmq_buffer, 0, bytes, 0, len);

                        MarketDataDepth mdd = MarketDataDepth.CreateBuilder().MergeFrom(bytes).Build();

                        PrintMarketDataDepth(mdd);
#if false
                        for (int i = 0; i < mdd.MdCount; i++)
                        {
                            MarketData md = mdd.MdList[i];

                            string timestamp = md.Time;
                            int index = timestamp.IndexOf(",");
                            if(-1 != index)
                                timestamp = timestamp.Remove(index);

                            DateTime parseResult;
                            if (false == System.DateTime.TryParseExact(timestamp, format, provider, DateTimeStyles.None, out parseResult))
                                continue;

                            var mde = new MarketDataEntity
                            {
                                NMDDTag = (long)mdd.NMDDTag,
                                QType = (0 == md.QuoteType ? QuoteType.Bid : QuoteType.Ask),
                                QPrice = md.Price,
                                QSize = md.Size,
                                QSource = md.Source,
                                QLiquidityTag = md.ID,
                                QSilo = md.Silo,
                                QTimeStamp = parseResult
                            };

                            dbTDC.MarketDataDbSet.Add(mde);

                            mdde.Depth.Add(mde);
                        }

                        if (0 == count % 500)
                            dbTDC.SaveChanges();
#endif
                    }
                }
            }
            catch (DbEntityValidationException e)
            {
                foreach (var eve in e.EntityValidationErrors)
                {
                    Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().Name, eve.Entry.State);
                    foreach (var ve in eve.ValidationErrors)
                    {
                        Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                        ve.PropertyName, ve.ErrorMessage);
                    }
                }

                throw;
            }
        }
    }

    public enum QuoteType { Bid = 0, Ask }

    public class MarketDataEntity
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int MarketDataEntityID { get; set; }

        public long NMDDTag { get; set; }
        public QuoteType QType { get; set; }
        public double QPrice { get; set; }
        public double QSize { get; set; }
        public string QSource { get; set; }
        public string QLiquidityTag { get; set; }
        public string QSilo { get; set;}
        [Column("timestamp", TypeName = "datetime2")]
        public DateTime QTimeStamp { get; set; }
    }

    public class MarketDataDepthEntity
    {
        public int MarketDataDepthEntityID { get; set; }
        public virtual IList<MarketDataEntity> Depth { get; set; }

        [Column("timestamp", TypeName = "datetime2")]
        public DateTime TimeStamp { get; set; }
        public MarketDataDepthEntity() { Depth = new List<MarketDataEntity>(); }
    }

    public class SymbolTickDataEntity
    {
        public int SymbolTickDataEntityID { get; set; }

        [Key]
        [Required]
        public string Symbol { get; set; }

        public virtual IList<MarketDataDepthEntity> Mdds { get; set; }
        public SymbolTickDataEntity() { Mdds = new List<MarketDataDepthEntity>(); }
    }

    public class TickDataTestContext : DbContext
    {
        public DbSet<MarketDataEntity> MarketDataDbSet { get; set; }
        public DbSet<MarketDataDepthEntity> MarketDataDepthDbSet { get; set; }
        public DbSet<SymbolTickDataEntity> SymbolTickDataDbSet { get; set; }
    }
4

1 回答 1

2

从您的代码看来,您在应用程序的整个生命周期中都在使用 TickDataTestContext。因此,当您不断添加数据时,本地缓存会不断增加内存使用量,从而导致性能下降。

您应该重写代码,为需要保存的每个请求创建一个新的 TickDataTestContext 实例,然后执行工作、保存更改并释放上下文。

于 2013-07-03T16:18:37.547 回答