2011年5月30日

Microsoft.Practices.Unity 的一个线程安全Bug浅析

摘要: 从接触Enterprise Library开始,到现在越来越感觉的Elib的强大。虽然单独看Elib里面的Block不一定是优秀的,但是作为一个整体其优势不言而喻。更重要的是Elib是MS的团队在维护,不用担心MS会把它吃掉。 这段时间一直在Elib上进行开发,Unity也是用的最多的一个Block了。由于都是在单机开发BS系统,因此很少应用到多线程,多线程的问题也没有怎么暴露出来。以前也潜意识的认为MS会把线程安全处理好,但是今天发现其实不然。测试代码如下:1classProgram2{3staticUnityContainercontainer;4staticboolstop;5stat.阅读全文

posted @ 2011-05-30 17:18 Kain 阅读(1087) 评论(6) 编辑

2011年3月14日

NET Reflector 7发布,其 不再免费

今天看到NET Reflector不再免费的消息感觉有点惊讶,这个工具已经成为每个开发人员必备的工具之一了。而且CodePlex上也有很多围绕NET Reflector开发的插件。今天其不再免费了,难道逼大家去Crack么?35美刀不便宜啊。

 

官方的原文:

10 Mar 2011


Version 7 is now available from $35.

We're happy to announce that we've released .NET Reflector 7. Please visit the new website at www.reflector.net to find out more and download a free 14 day trial.

The free version of .NET Reflector is no longer available. Please see our original announcement below. 

posted @ 2011-03-14 10:11 Kain 阅读(8540) 评论(87) 编辑

2010年8月19日

(抽象)工厂的另一种实现方式

工厂模式是在设计模式中比较容易理解和掌握的一种模式,其使用非常的普遍。在项目实践中个人对常用的工厂模式做了一个调整,整个实现有点像工厂模式和抽象工厂模式的混合体,这样做的好处在于结合工厂模式的易用和抽象工厂的灵活。具体的实现可能如下:

在这个Case中有2个类,2个接口。其中IServiceFactory定义了工厂的职责GetService<T>,ServiceFactory实现IServiceFactory接口(注意接口是显示实现,这个很重要,因为类的静态方法和实例方法签名不能相同)。

 ServiceFactory.cs

代码
 1     public class ServiceFactory:IServiceFactory
 2     {
 3         private static IServiceFactory _inc;
 4 
 5         private ServiceFactory()
 6         { 
 7 
 8         }
 9         static ServiceFactory()
10         { 
11 
12             _inc = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<IServiceFactory>();
13             if (_inc == null)
14 
15                 _inc = new ServiceFactory();
16         }
17 
18         public static T GetService<T>()
19         {
20             return _inc.GetService<T>();
21         }
22 
23         T IServiceFactory.GetService<T>()
24         {
25             return default(T);
26         }
27     }

 

 作为ServiceFactory的调用者在使用上和普通的工厂没有任何区别,利用IOC容器可以非常方便的用Mok对象来降低对具体业务的依赖性,极大的了方便单元测试。同时我们也可以通过条件编译在发布的时候去掉对IoC容器的依赖。

Test:

 

代码
 1  IUnityContainer container;
 2         [Test]
 3         public void CalculateTest()
 4         {
 5             Setup();
 6 
 7             var factoryMock = new Mock<IServiceFactory>();//Mock Factory
 8             var calcMock = new Mock<ICalculateService>();//Mock Service
 9             calcMock.Setup(c => c.Sum(It.IsAny<int>(), It.IsAny<int>())).Returns<intint>((x, y) => x + y); //Mock Calculate Sum Method
10             factoryMock.Setup(c => c.GetService<ICalculateService>()).Returns(calcMock.Object); //Mock GetService<T> Method
11             
12             container.RegisterInstance<IServiceFactory>(factoryMock.Object);//向容器中注入Mock的Factory
13 
14             var calc = ServiceFactory.GetService<ICalculateService>();
15 
16             Assert.IsNotNull(calc);
17             int a = 1;
18             int b = 2;
19             int experct = a + b;
20             int actual = calc.Sum(a, b);
21             Assert.IsTrue(experct == actual);
22         }
23 
24         public void Setup()
25         {
26             container = new UnityContainer();
27             Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current = new UnityServiceLocator(container);
28         }

 

 

posted @ 2010-08-19 17:51 Kain 阅读(1015) 评论(1) 编辑

2010年8月13日

自定义EF4 Model 代码生成

     在VS2010中EF4提供了三种代码生成方式:EntityObject,POCO,Self-Tacking。默认VS2010只带有EntityObject模板,可以通过浏览Online Templates中的项目将剩余的两种添加到本地模板文件中来。三种代码模板都是通过T4模板引擎来实现的,因此通过分析一下模板文件我们也能够实现自己的代码生成器。

     在项目中添加一个模板文件,打开.tt的文件,在文件的头部会有一行代码<#@ include file="EF.Utility.CS.ttinclude"#>,EF.Utility.CS.ttinclude是一个非常有用的文件,主要是用来分析edmx文件和生成模型代码的,要实现自己的代码生成器首先得找到这个文件,通过搜索这个文件放置在:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes目录。用VS打开这个文件发现它其实就是个代码文件。新建一个Project将文件中的CS代码copy到一个新的CodeGenerationTools类中,引用必要的Assembly和Namespace就可以了。在本文附件中找到两个Dll:Microsoft.VisualStudio.TextTemplating.10.0.dll和Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.dll 这两个dll是T4模板的引擎,具体的使用在网上有很多介绍这里就不再赘述了。在项目中添加EntityObject,POCO,Self-Tacking三个模板文件,将默认文件名改成对应的模板名称,这样便于区分。在添加模板文件的时候IDE可能会出现很多Error信息,直接跳过可以了。在出错信息中会有个错误信息说需要用实际的edmx文件路径替换掉 $edmxInputFile$ 。这个地方就是后面我们需要修改的地方。选择tt模板文件在文件属性中将Customer Tool里面的内容清空,这样IDE就不会自动生成不必要的cs文件也不会提示错误了。在项目文件中新增一个新类EntityFrameworkTemplateHost实现ITextTemplatingEngineHost接口。这类将来主要负责传递一些配置信息。具体的代码可以在附件中找到这里面就不贴了,网上关于T4模板介绍的中都有其使用介绍。

      完成这些就需要对模板文件和CodeGenerationTools中的内容做一些调整。首先是修改每个模板文件在在每个模板的头中添加必要的名称空间引用,如果后面的执行中出现类型找不到就是在这里没有添加必要的名称空间了。在模板文件中找到带有$edmxInputFile$文本的哪行,将其替换为:

EntityFrameworkTemplateHost host = (EntityFrameworkTemplateHost)(Host);
string inputFile = host.EDMXFile;//EDMXFile是EntityFrameworkTemplateHost定义的一个属性由外部传入。

打开CodeGenerationTools文件,去掉EnvDTE引用,因为这个是在IDE环境中用到的,这里我们不需要和IDE交互所以可以完全移除了。这个过程比较简单,根据编译错误可以很容易调整过了,这里限于篇幅限制就不详细介绍了。最后的调用代码可能是这样:


整个过程其实比较简单的,就不放完整的代码了,动动手有益健康。附件

posted @ 2010-08-13 10:41 Kain 阅读(1331) 评论(1) 编辑

2010年8月12日

.net 4.0 中对多线程新特性(四)--任务和任务工厂

在4.0前如果需要进行并行任务往往都是自己实现Task和Task Factory来管理任务,其中难免会牵涉到大量的线程和线程池的管理工作。到了4.0 这部分内容都已经集成到基础类库中了。在System.Threading.Task中新增了几个类:

Task

TaskFactory

TaskScheduler

这几个类一看名字就知道干啥的了,先看看Task的一个简单例子

 

代码
 1 [STAThread]
 2         static void Main()
 3         {
 4             var tasks = new Task[10];
 5             for (int i = 0; i < 10; i++)
 6             {
 7                 tasks[i] =   new Task(Action,TaskCreationOptions.LongRunning);
 8                 tasks[i].Start();
 9             }
10             
11             //Task.WaitAll(tasks);
12 
13             Console.WriteLine("Finished");
14             Console.ReadLine();
15         }
16 
17         static Random rd = new Random();
18         static void Action()
19         {
20             var threadId = Thread.CurrentThread.ManagedThreadId;
21             Console.WriteLine("Current Thread Id:{0}" ,threadId);
22             Thread.Sleep(rd.Next(1001000));//随机休眠一段时间,模拟线程实际调用时间消耗
23         }

 

 

程序输出如下:
Current Thread Id:11
Finished
Current Thread Id:12
Current Thread Id:14
Current Thread Id:13
...
(实际的输出可能和这里有所不同)
细心的你可能会发现代码中的第11行已经被注释了,WaitAll的名字是不是非常熟悉?是的,这在我们做线程同步时经常会用到WaitHandle类的WaitAll效果是一样的
取消注释运运行一下我们会得到如下输出:
Current Thread Id:11
Current Thread Id:12
Current Thread Id:14
Current Thread Id:13
...
Finished

在输出中的Finished一定会等所有的Task完成之后才会输出。是不是非常容易了。Task启动的时候会自动使用到线程池,系统会给Task自动分配线程。

如果任务很多的时时候我们需要细粒度的控制每个Taks的调度Schedule可以用TaskFactory就是来完成做这个工作的,看个简单的例子:

 

代码
 1 [STAThread]
 2         static void Main()
 3         {
 4             var factory = new TaskFactory();
 5             var tasks = new Task[10];
 6             for (int i = 0; i < 10; i++)
 7             {
 8                 tasks[i] = factory.StartNew(Action );
 9             }
10             
11             Task.WaitAll(tasks);
12 
13             Console.WriteLine("Finished");
14             Console.ReadLine();
15         }
16 
17         static Random rd = new Random();
18         static void Action()
19         {
20             var threadId = Thread.CurrentThread.ManagedThreadId;
21             Console.WriteLine("Current Thread Id:{0}" ,threadId);
22             Thread.Sleep(rd.Next(1001000));//随机休眠一段时间,模拟线程实际调用时间消耗
23         }

 

程序输出如下:

Current Thread Id:11
Current Thread Id:11
Current Thread Id:12
Current Thread Id:11
Current Thread Id:11
Current Thread Id:12
Current Thread Id:11
Current Thread Id:12
Current Thread Id:11
Current Thread Id:12
Finished

从结果中看到10个任务只分配到了2个线程来处理,线程被最大的限度的复用了。如果需要更好的控制任务的调度,你需显示的配置TaskScheduler,对于你来说应该非常easy的 

posted @ 2010-08-12 17:12 Kain 阅读(1699) 评论(0) 编辑

2010年8月10日

.net 4.0 中对多线程新特性(三)

摘要: 在4.0之前如果需要在多线程环境下操作集合类型的对象往往需要额为每种操作添加比较复杂的锁机制才能保证每个线程对资源的访问安全,在4.0的Collection名称空间下面又多了一个新的名称空间Concurrent,在这个名称空间下面增加了几个非常有用的线程安全的类:BlockingCollection<T> 为实现 IProducerConsumerCollection<(Of &...阅读全文

posted @ 2010-08-10 14:32 Kain 阅读(1937) 评论(2) 编辑

2010年8月9日

.net 4.0 中对多线程新特性(二)

摘要: 上篇已经简单介绍了.net 4.0中Lazy<T>类,通过Lazy<T>我们可以很容易的延迟初始化一些对象。如果我们需要在多线程环境下建立一些线程级别应用可以使用ThreadLocal<T>。在MSND中我们可以了解到除了Dispose之外,ThreadLocal<T> 的所有公共和受保护的成员都是线程安全的,可从多个线程同时使用。Value 和 I...阅读全文

posted @ 2010-08-09 13:51 Kain 阅读(1937) 评论(1) 编辑

2010年7月30日

.net 4.0 中对多线程新特性(一)

摘要: 在.net 40中对多线程的处理增加了很多新的类以方便多线程环境下的编程实现,首先需要了解的是两个非常有用的类Lazy<T>和ThreadLazy<T>,通过这两个类我们可以很方便实现一个单例模式而不用考虑太多的线程安全的问题。 Lazy<T>:类简化了执行对象的延迟初始化和实例化的工作。通过以延迟方式实例化对象,可避免在根本不需要的情况下必须创建所有的对象,或...阅读全文

posted @ 2010-07-30 16:32 Kain 阅读(1816) 评论(5) 编辑

2007年12月13日

Flex&.Net开篇

摘要: Flex学习心得和一些Flex资料推荐
阅读全文

posted @ 2007-12-13 11:43 Kain 阅读(256) 评论(0) 编辑

2007年11月2日

SqlSever N层表数据查询效率

摘要: 在做数据内联查询时,随着Join的表越多查询的性能会急剧下降。为了提高查询这种深层次对象的效率,采用了一种折中的办法就是将相邻两个表作join将主键插入一个表变量,然后作为下一个表查询的条件阅读全文

posted @ 2007-11-02 11:08 Kain 阅读(1745) 评论(7) 编辑

导航

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

公告

昵称:Kain
园龄:8年
粉丝:5
关注:0

搜索

 
 

常用链接

我的标签

随笔分类

随笔档案

文章分类

文章档案

相册

dotNet

最新评论

阅读排行榜

评论排行榜

推荐排行榜