对于自我管理 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();
       }
 
 
   }

 

内在状况:

image

看了一下,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;
           }
 
       }

 

然后这样就,呵呵了。

image

 

是的,对于多线程下,不能使用共享的Context。

下面也给出了解决方法。

http://stackoverflow.com/questions/9415955/c-sharp-working-with-entity-framework-in-a-multi-threaded-server

 

看完这个以后,我顿时明白了。

我的错误在于,为了所谓的性能考虑。

使用了

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)

posted @ 2014-01-25 16:39  张保维  阅读(274)  评论(0编辑  收藏  举报