对于自我管理 ObjectContextManager的测试
书接上文,
把代码改为多线程,
public class Threads
{
public static void allStart()
{
for (int i = 0; i < 10; i++)
{
t1();
}
}
public static void t1()
{
var t = new Thread(() =>
{
Class1.Test();
});
t.IsBackground = true;
t.Start();
}
}
内在状况:
看了一下,CPU相当的同,但是内存已经没问题了。
现在从读的情况来看没什么问题。
把代码再改改。
public class Class1
{
private static Domain.Entities.Models.passportContext context;
static Class1()
{
context =
new Domain.Entities.Models.passportContext("passportContext");
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.LazyLoadingEnabled = false;
var om = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager;
om.ObjectStateManagerChanged += om_ObjectStateManagerChanged;
}
public static void Test()
{
var start = int.MaxValue;
while (true)
{
var list = context.UserSources.OrderByDescending(x => x.UserId).Where(x => x.UserId < start).Take(100).ToList();
ObjectContext oc = ((IObjectContextAdapter)context).ObjectContext;
var m = oc.ObjectStateManager;
var a = list.First();
var count = GetUnchangedCount(context);
ClearUnchangedCache(context);
ClearKeylessEntityCache(context);
count = GetUnchangedCount(context);
Console.WriteLine(string.Format("[{0}]", Thread.CurrentThread.ManagedThreadId) + a.UserId);
//context.SaveChanges();
//ClearCache(context);
start = a.UserId;
}
}
然后这样就,呵呵了。
是的,对于多线程下,不能使用共享的Context。
下面也给出了解决方法。
看完这个以后,我顿时明白了。
我的错误在于,为了所谓的性能考虑。
使用了
public abstract class StatBase<TSource, TStat>
where TSource : class
where TStat : class
{
protected readonly GenericRepository<TSource> Sourcelog;
protected readonly GenericRepository<TStat> Stat;
protected readonly SingleFileLine Sfl;
private int sleep = 45;
public event EventHandler<InfoEventArgs> StateInfo;
protected virtual void OnStateInfo(InfoEventArgs e)
{
EventHandler<InfoEventArgs> handler = this.StateInfo;
if (handler != null) handler(this, e);
}
protected virtual void OnState(InfoEventArgs e)
{
EventHandler<InfoEventArgs> handler = this.StateInfo;
if (handler != null) handler(this, e);
}
protected virtual void OnState(string info)
{
EventHandler<InfoEventArgs> handler = this.StateInfo;
if (handler != null) handler(this, new InfoEventArgs
{
Info = info,
Time = System.DateTime.Now
});
}
protected StatBase()
{
this.Sourcelog = new GenericRepository<TSource>(AppIniter.DefaultConnection);
this.Stat = new GenericRepository<TStat>(AppIniter.DefaultConnection);
this.Sfl = new SingleFileLine(typeof(TStat).Name);
}
在构造中对Responstory进行实例化,然后再多线程中使用,所以就出现了上个文章中的问题。内存不断的增长。
那这样,改下程序,把实例化的过程放到线程中,每次使用实例化一个对象,然后超出作用域后就自动释放。
这是一个好的想法,但不帅了,不过,可以试试的。
代码就变成 了这样。
public abstract class StatBase<TSource, TStat>
where TSource : class
where TStat : class
{
protected GenericRepository<TSource> Sourcelog
{
get
{
return new GenericRepository<TSource>(AppIniter.DefaultConnection);
}
}
protected GenericRepository<TStat> Stat
{
get
{
return new GenericRepository<TStat>(AppIniter.DefaultConnection);
}
}
但是处理速度上明显就下去了。
*》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
其实整体上没有解决,没有按上面的路走下去,直接使用的就是 using(context)