代码优先会随着时间的推移而降级

本文关键字:降级 时间 代码 | 更新日期: 2023-09-27 18:21:04

下面的程序是一个套接字程序,可以很快地接收数据。它在禁用CodeFirst部分的情况下运行良好。如果我启用它,程序开始时会很好,但随后会缓慢降级到似乎没有任何内容写入SQL EXPRESS 2012数据库的地步。我通过运行下面的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; }
    }

代码优先会随着时间的推移而降级

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

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