Linq to Entity 中 , Query不应该有耗时操作
Linq to Entity 是一个非常棒的工具。
但是如果“滥用”就会发生奇怪的问题。
最近的项目中,遇到如下境况:
有300个表结构一致的表(拗口),需要逐一读取300个表的一个数据,排序,然后取出最小的那个数(假设这个数属于表TableA),然后从TableA中再取一个数,排序.......
然后我用Samphore,大致代码如下:
class QHelper { public QHelper(IEnumerable<TickData> arg_Q,string arg_strSelectQuery , MarketContext arg_MarketContext) { SelectQueryString = arg_strSelectQuery; Q = arg_Q; MarketContext = arg_MarketContext; _task = new Task(() => { foreach (var data in Q) { norlib.DebugHelper.DebugHelper.Set(arg_strSelectQuery , "wait data"); _sph.WaitOne(); norlib.DebugHelper.DebugHelper.Set(arg_strSelectQuery, "got data"); _data = data; } IsCompleted = true; }); _task.Start(); } public IEnumerable<TickData> Q { get; private set; } public TickData Data { get { lock (_lockGetData) { if (IsCompleted) return null; _sph.Release(); while (true) { if (IsCompleted) return null; if (_data != null) { var ret = _data; _data = null; return ret; } Thread.Sleep(100); } } } } public string SelectQueryString { get; set; } public bool IsCompleted { get; private set; } Task _task; TickData _data; Semaphore _sph = new Semaphore(0, 1); MarketContext MarketContext; object _lockGetData = new object(); }
用户只需要不断读取Data,直到返回null就可以了。
Query也对用户隐藏了。
写完感觉良好。
跑起来后就发现问题有2个。
1.300个表速度很慢,就是Data 获取的很慢
2. 在跑了一段时间后,会出现2种错误:1.远程连接被关闭 2. EndOfStreamException
个人认为这都是因为Query长时间处于非工作状态,导致mysql关闭连接所致。(Entity to SQL使用 连接池)
最后只得牺牲空间,Query中去掉等待,直接加入Queue
解决了速度问题和错误的问题,当然内存的损耗也很惊人。(⊙_⊙)