知识大全 EntityFramework用法探索:线程安全实践

Posted

篇首语:捐躯赴国难,视死忽如归。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 EntityFramework用法探索:线程安全实践相关的知识,希望对你有一定的参考价值。

EntityFramework用法探索:线程安全实践  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  在前文中 我们通过Unity来注册各种类型和WiringUp

   IUnityContainer container = new UnityContainer()

   RegisterType(typeof(IRepository<>) typeof(Repository<>) new ContainerControlledLifetimeManager())

   RegisterType (new ContainerControlledLifetimeManager())

   RegisterType (new ContainerControlledLifetimeManager())

   RegisterType (new ContainerControlledLifetimeManager())

   RegisterType (new ContainerControlledLifetimeManager())

   RegisterType (new ContainerControlledLifetimeManager())

   RegisterType (new ContainerControlledLifetimeManager());

  

   UnityServiceLocator locator = new UnityServiceLocator(container);

   ServiceLocator SetLocatorProvider(() => locator);

  

   ICustomerRepository customerRepository = container Resolve ();

  但选择使用了ContainerControlledLifetimeManager对象生命周期管理器 其将每个对象存储为Singleton 这导致在多线程环境下会产生异常

  例如我们尝试在多线程条件下更新Customer表

   List tasks = new List ();

   for (int i = ; i < ; i++)

  

   DomainModels Customer modifiedCustomer = Mapper Map (customer );

   modifiedCustomer Name = modifiedCustomer Name + i;

  

   Task t = Task Factory StartNew(() =>

  

   try

  

   customerRepository UpdateCustomer(modifiedCustomer);

  

   catch (Exception ex)

  

   Console WriteLine( Exception occurred in thread + Thread CurrentThread ManagedThreadId);

   Console WriteLine(ex Message);

  

   );

   tasks Add(t);

  

   Task WaitAll(tasks ToArray());

>

  但由于我们仍然需要EntityFramework的Local功能 即在当前线程环境下始终使用当前上下文中的对象 我们可能还无法选择其他Unity对象生命期管理模型

  此时 我们考虑一种新的方法 引入线程Scope功能 即在给定线程中 使用同一个UnityContainer来维护对象 这样间接利用的EntityFramework的上下文功能

  原理很简单 就是为每个线程生成一个单独的ChildUnityContainer

   public class UnityContainerScope : IDisposable

  

   private static ConcurrentDictionary scopeMapping

   = new ConcurrentDictionary ();

  

   protected UnityContainerScope()

  

   ScopeId = Thread CurrentThread ManagedThreadId;

   scopeMapping Add(ScopeId true);

  

  

   public int ScopeId get; private set;

   public static int ScopeCount get return scopeMapping Count;

  

   public static UnityContainerScope NewScope()

  

   return new UnityContainerScope();

  

  

   public static bool InScope(int scopeId)

  

   return scopeMapping ContainsKey(scopeId);

  

  

   public void Dispose()

  

   UnityContainerDispatcher DisposeContainer();

   scopeMapping Remove(ScopeId);

  

  

  这里同时需要一个UnityContainerDispatcher来负责为线程生成Container容器

   public static class UnityContainerDispatcher

  

   private static IUnityContainer parentContainer = null;

   private static ConcurrentDictionary containerMapping

   = new ConcurrentDictionary ();

  

   public static void InjectParentContainer(IUnityContainer unity)

  

   if (unity == null)

   throw new ArgumentNullException( unity );

  

   parentContainer = unity;

  

  

   public static IUnityContainer GetContainer()

  

   int key = Thread CurrentThread ManagedThreadId;

  

   if (!UnityContainerScope InScope(key))

  

   throw new UnityContainerNotInScopeException(

   string Format(CultureInfo InvariantCulture

   The specified scope id [ ] is not in scope key));

  

  

   if (!containerMapping ContainsKey(key))

  

   BuildUpContainer(key);

  

  

   return containerMapping Get(key);

  

  

   public static void DisposeContainer()

  

   int key = Thread CurrentThread ManagedThreadId;

   IUnityContainer container = containerMapping Remove(key);

   if (container != null)

  

   container Dispose();

  

  

  

   private static void BuildUpContainer(int key)

  

   if (parentContainer == null)

   throw new InvalidProgramException( The parent container cannot be null );

  

   IUnityContainer childContainer = parentContainer CreateChildContainer();

   containerMapping Add(key childContainer);

  

  

  在注入的根UnityContainer中 我们通过使用CreateChildContainer方法来获取一个新的Container 同时继承所有根容器的注册配置信息 这要求使用HierarchicalLifetimeManager生命期管理器

  此时 我们的代码修改为

   IUnityContainer container = new UnityContainer()

   RegisterType(typeof(IRepository<>) typeof(Repository<>) new HierarchicalLifetimeManager())

   RegisterType (new HierarchicalLifetimeManager())

   RegisterType (new HierarchicalLifetimeManager())

   RegisterType (new HierarchicalLifetimeManager())

   RegisterType (new HierarchicalLifetimeManager())

   RegisterType (new HierarchicalLifetimeManager())

   RegisterType (new HierarchicalLifetimeManager());

  

   UnityContainerDispatcher InjectParentContainer(container);

  

   ICustomerRepository customerRepository = container Resolve ();

  创建多线程测试代码

   List tasks = new List ();

   for (int i = ; i < ; i++)

  

   DomainModels Customer modifiedCustomer = Mapper Map (customer );

   modifiedCustomer Name = modifiedCustomer Name + i;

  

   Task t = Task Factory StartNew(() =>

  

   try

  

   using (UnityContainerScope scope = UnityContainerScope NewScope())

  

   customerRepository UpdateCustomer(modifiedCustomer);

   Console WriteLine( Modified + modifiedCustomer Name + in thread + Thread CurrentThread ManagedThreadId);

  

  

   catch (Exception ex)

  

   Console WriteLine( Exception occurred in thread + Thread CurrentThread ManagedThreadId);

   Console WriteLine(ex Message);

  

   );

   tasks Add(t);

  

   Task WaitAll(tasks ToArray());

  测试结果表明已经可以安全的在多线程条件下工作了

> cha138/Article/program/net/201311/12626

相关参考

知识大全 java多线程中synchronized关键字的用法

  由于同一进程内的多个线程共享内存空间在Java中就是共享实例当多个线程试图同时修改某个实例的内容时就会造成冲突因此线程必须实现共享互斥使多线程同步  最简单的同步是将一个方法标记为synchron

知识大全 编写高效的线程安全类

 在语言级支持锁定对象和线程间发信使编写线程安全类变得简单本文使用简单的编程示例来说明开发高效的线程安全类是多么有效而直观  Java编程语言为编写多线程应用程序提供强大的语言支持但是编写有用的没有错

知识大全 C#多线程中lock的用法

C#多线程中lock的用法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  经常碰到同时需要对某个

知识大全 破除java神话之原子操作都是线程安全的

  java中原子操作是线程安全的论调经常被提到根据定义原子操作是不会被打断地的操作因此被认为是线程安全的实际上有一些原子操作不一定是线程安全的    这个问题出现的原因是尽量减少在代码中同步关键字同

知识大全 Java线程安全总结

Java线程安全总结  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  最近想将java基础的一些东

知识大全 Java理论与实践: 描绘线程安全性[2]

Java理论与实践:描绘线程安全性[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  线程安全

知识大全 Java理论与实践: 描绘线程安全性[1]

Java理论与实践:描绘线程安全性[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  定义线程

知识大全 Java容器类的线程安全

Java容器类的线程安全  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java容器类的关系图 

知识大全 基于Spring+Ibatis的安全线程实现

基于Spring+Ibatis的安全线程实现  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  过去

知识大全 深入研究Servlet线程安全性问题

深入研究Servlet线程安全性问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Servle