一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Asp.net

“锁定”语句(C# 参考)

lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。 下面的示例包含一个 lock 语句。

有关更多信息,请参见 线程同步(C# 和 Visual Basic)。 备注 lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。 线程处理(C# 和 Visual Basic) 这节讨论了线程处理。 lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。 通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。 常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则: 如果实例可以被公共访问,将出现 lock (this) 问题。 如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。 由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。 最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。 在 lock 语句的正文不能使用 等待 关键字。 示例 下面演示在 C# 中使用未锁定的线程的简单示例。 C#

示例 下例使用线程和 lock。 只要 lock 语句存在,语句块就是临界区并且 balance 永远不会是负数。 C#

from:https://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx

龙生   17 Sep 2016
View Details

Entity Framework 增删改查和事务操作

1、增加对象

2、删除对象,删除只需要对象的主键

3、修改对象 方法一:

方法二:方法一中每次都需要对所有字段进行修改,效率低,而且麻烦,下面介绍修改部分字段

4、使用事务:使用事务很简单,只要把需要的操作放在 TransactionScope 中,最后提交

5、查询:查询通过LinQ查询

  from:http://www.cnblogs.com/bomo/p/3331602.html

龙生   15 Sep 2016
View Details

Entity Framework中的批量提交与事务处理

在Entity Framework 中使用SaveChanges()是很频繁的,单次修改或删除数据后调用SaveChanges()返回影响记录数。 要使用批量修改或者批量删除数据,就需要SaveChanges(false)+AcceptAllChanges()方法了。 SaveChanges(false) 只是通知EF需要对数据库执行的操作,在内存中是属于挂起状态,在必要的时候是可以撤销的,比如AcceptAllChange()提交为真正成功,EF将撤销SaveChanges(false)的操作。  而在处理分布式事务操作的时候,就有必要使用TransactionScope 来处理了,很多时候我们会这样写:

但是这样写是有风险的,假  如context1.SaveChanges()成功了,context2.SaveChanges()却是有问题的,我们在scope.Complete()提交事务的时候就会终止,而Context1已经成功执行了 这可能不一定符合我们的需要。如果我们需要 context1、context2要不同时执行成功,要不都不成功,我们需要对代码作小小的调整,如用下面的代码:   

我们用SaveChanges(false)先将必要的数据库操作命令发送给数据库,这是注意context1与context2并没有真正发生改变,如果事务终止,自动回滚,两者的更改都没有真正提交到数据库,所以是可以成功回滚的。 在Entity Framework 中使用SaveChanges()是很频繁的,单次修改或删除数据后调用SaveChanges()返回影响记录数。 要使用批量修改或者批量删除数据,就需要SaveChanges(false)+AcceptAllChanges()方法了。 SaveChanges(false) 只是通知EF需要对数据库执行的操作,在内存中是属于挂起状态,在必要的时候是可以撤销的,比如AcceptAllChange()提交为真正成功,EF将撤销SaveChanges(false)的操作。  而在处理分布式事务操作的时候,就有必要使用TransactionScope 来处理了,很多时候我们会这样写:

但是这样写是有风险的,假  如context1.SaveChanges()成功了,context2.SaveChanges()却是有问题的,我们在scope.Complete()提交事务的时候就会终止,而Context1已经成功执行了 这可能不一定符合我们的需要。如果我们需要 context1、context2要不同时执行成功,要不都不成功,我们需要对代码作小小的调整,如用下面的代码:   

我们用SaveChanges(false)先将必要的数据库操作命令发送给数据库,这是注意context1与context2并没有真正发生改变,如果事务终止,自动回滚,两者的更改都没有真正提交到数据库,所以是可以成功回滚的。 To use TransactionScope class you need to keep two things in mind You need to add System.Transactions reference to your project Make sure the Windows service “Distributed Transaction Coordinator” is up and running. from:http://www.cnblogs.com/hyl8218/archive/2011/10/10/2205576.html

龙生   15 Sep 2016
View Details

EntityFramework之异步、事务及性能优化(九)

前言 本文开始前我将循序渐进先了解下实现EF中的异步,并将重点主要是放在EF中的事务以及性能优化上,希望通过此文能够帮助到你。 异步 既然是异步我们就得知道我们知道在什么情况下需要使用异步编程,当等待一个比较耗时的操作时,可以用异步来释放当前的托管线程而无需等待,从而在管理线程中不需要花费额外的时间,也就是不会阻塞当前线程的运行。 在客户端如:Windows Form以及WPF应用程序中,当执行异步操作时,则当前线程能够保持用户界面持续响应。在服务器端如:ASP.NET应用程序中,执行异步操作可以用来处理多个请求,可以提高服务器的吞吐量等等。 在大部分应用程序中,对于比较耗时的操作用异步来实现可能会有一些改善,但是若你不多加考虑,动不动就用异步反而会得到相反的效果以及对应用程序也是致命的。 鉴于上述描述,我们接下来通过EF实现异步来加深理解。(想想还是把所用类及映射给出来,以免没看过前面的文章的同仁不知所云。) Student(学生)类:

Flower(小红花)类

  相关映射:

接下来我们添加相关数据并实现异步:

接下来就是在控制台进行调用以及输出:

  这段代码不难理解,基于我们对于异步的理解,输出顺序应该是(1)(3)(2)(4),结果如我们预期一样,如下: 我们知道await关键字的作用是: 在线程池中新起一个将被执行的工作线程Task,当要执行IO操作时则会将工作线程归还给线程池,因此await所在的方法不会被阻塞。当此任务完成后将会执行该关键字之后代码! 所以当执行到await关键字时,此时会在线程池中新开一个工作线程Id为11,此时要执行添加数据,所以此时将线程归还给主线程,不阻塞主线程的运行所以就出现先执行(2)而不是先执行(4)。 接下来看一个稍微在上述基础上经过改造的方法。如下:

接下来在控制台中进行如下调用:

  接下我们进行打印如下: 上述至于为什么不是执行【执行异步操作后,当前线程Id为10】然后执行【遍历获得所有学生的姓名,当前线程Id为12】,想必大家能清楚的明白,是执行上述 task.Wait() 的缘故,必须进行等待当前任务执行完再执行主线程后面的输出。 对于处理EF中的异步没有太多去探索的东西,基本就是调用EF中对应的异步方法即可,重点是EF中的事务,请继续往下看: *事务 默认情况下 可能我们未曾注意到,其实在EF的所有版本中,当我们调用SaveChanges方法来执行增、删、改时其操作内部都用一个transaction包裹着。不信,如下图,当添加数据时: 对于上下文中的  ExecuteSqlCommand()  方法默认情况下也是用transaction包裹着命令(Command),其有重载我们可以显示指定执行事务还是不确定执行事务。 在此上两种情况下,事务的隔离级别是数据库提供者认为的默认设置的任何隔离级别,例如在SQL Server上默认是READ COMMITED(读提交)。 EF对于任何查询都不会用transaction来进行包裹。 在EF 6.0版本以上,EF一直保持数据库连接打开,因为要启动一个transaction必须是在数据库连接打开的前提下,同时这也就意味着我们执行多个操作在一个transaction的唯一方式是要么使用 TransactionScope 要么使用  ObjectContext.Connection 属性并且启动调用Open()方法以及BeginTransaction()方法直接返回EntityConnection对象。如果你在底层数据库连接上启动了transaction,再调用API连接数据库可能会失败。 概念 在开始学习事务之前我们先了解两个概念: Database.BeginTransaction() :它是在一个已存在的DbContext上下文中对于我们去启动和完成transactions的一种简单方式,它允许多个操作组合存在在相同的transaction中,所以要么提交要么全部作为一体回滚,同时它也允许我们更加容易的去显示指定transaction的隔离级别。 Dtabase.UseTransaction() :它允许DbContext上下文使用一个在EF实体框架之外启动的transaction。 在相同上下文中组合几个操作到一个transaction Database.BeginTransaction有两种重载——一种是显示指定隔离级别,一种是无参数使用来自于底层数据库提供的默认隔离级别,两种都是返回一个DbContextTransaction对象,该对象提供了事务提交(Commint)以及回滚(RollBack)方法直接表现在底层数据库上的事务提交以及事务回滚上。 DbContextTransaction一旦被提交或者回滚就会被Disposed,所以我们使用它的简单的方式就是使用using(){}语法,当using构造块完成时会自动调用Dispose()方法。 根据上述我们现在通过两个步骤来对学生进行操作,并在同一transaction上提交。如下:

我们通过控制台输出SQL日志查看提交事务成功如下: 【注意】 要开始一个事务必须保持底层数据库连接是打开的,如果数据库不总是打开的我们可以通过 BeginTransaction() 方法将打开数据库连接,如果  DbContextTransaction 打开了数据库,当调用Disposed()方法时将会关闭数据库连接。 注意事项 当用EF上下文中的 Database.ExecuteSqlCommand 方法来对数据库进行如下操作时

  此时将会报错如下: 上述已经讲过此方法会被Transaction包裹着,所以导致出错,但是此方法有重载,我们进行如下设置即可

  将一个已存在的事务添加到上下文中 有时候我们可能需要事务的作用域更加广一点,当然是在同一数据库上但是是在EF之外完全进行操作。基于此,此时我们必须手动打开底层的数据库连接来启动事务,同时通知EF使用我们手动打开的连接来使现有的事务连接在此连接上,这样就达到了使用在EF之外的事务。 为了实现上述在EF之外使用事务我们必须在DbContext上下文中的派生类的构造器中关闭自身的连接而使用我们传入的连接。 第一步 上下文中关闭EF连接使用底层连接。 代码如下:

  第二步 启动Transcation(如果我们想避免默认设置我们可以手动设置隔离级别),通知EF一个已存在的Transaction已经在我们手动的设置的底层连接上启动。 […]

龙生   15 Sep 2016
View Details

5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq

在上一篇博客5天玩转C#并行和多线程编程 —— 第一天 认识Parallel中,我们学习了Parallel的用法。并行编程,本质上是多线程的编程,那么当多个线程同时处理一个任务的时候,必然会出现资源访问问题,及所谓的线程安全。就像现实中,我们开发项目,就是一个并行的例子,把不同的模块分给不同的人,同时进行,才能在短的时间内做出大的项目。如果大家都只管自己写自己的代码,写完后发现合并不到一起,那么这种并行就没有了意义。   并行算法的出现,随之而产生的也就有了并行集合,及线程安全集合;微软向的也算周到,没有忘记linq,也推出了linq的并行版本,plinq – Parallel Linq.  一、并行集合 —— 线程安全集合   并行计算使用的多个线程同时进行计算,所以要控制每个线程对资源的访问,我们先来看一下平时常用的List<T>集合,在并行计算下的表现,新建一个控制台应用程序,添加一个PEnumerable类(当然你也直接写到main方法里面测试,建议分开写),写如下方法:

点击F5运行,得到如下结果: 看到结果中显示的5851,但是我们循环的是10000次啊!怎么结果不对呢?这是因为List<T>是非线程安全集合,意思就是说所有的线程都可以修改他的值。 下面我们来看下并行集合 —— 线程安全集合,在System.Collections.Concurrent命名空间中,首先来看一下ConcurrentBag<T>泛型集合,其用法和List<T>类似,先来写个方法测试一下:

同时执行两个方法,结果如下: 可以看到,ConcurrentBag集合的结果是正确的。下面我们修改代码看看ConcurrentBag里面的数据到底是怎么存放的,修改代码如下:

先来看一下运行结果: 可以看到,ConcurrentBag中的数据并不是按照顺序排列的,顺序是乱的,随机的。我们平时使用的Max、First、Last等linq方法都还有。其时分类似Enumerable的用法,大家可以参考微软的MSDN了解它的具体用法。 关于线程安全的集合还有很多,和我们平时用的集合都差不多,比如类似Dictionary的ConcurrentDictionary,还有ConcurrentStack,ConcurrentQueue等。    二、Parallel Linq的用法及性能 1、AsParallel 前面了解了并行的For和foreach,今天就来看一下Linq的并行版本是怎么样吧?为了测试,我们添加一个Custom类,代码如下:

写如下测试代码:

其实也就是加了一个AsParallel()方法,下面来看下运行结果: 时间相差了一倍,不过有时候不会相差这么多,要看系统当前的资源利用率。大家可以多测试一下。 其实,AsParallel()这个方法可以应用与任何集合,包括List<T>集合,从而提高查询速度和系统性能。   2、GroupBy方法 在项目中,我们经常要对数据做处理,比如分组统计,我们知道在linq中也可以实现,今天来学习一下新的ToLookup方法,写一个测试方法,代码如下:

运行结果如下: ToLookup方法是将集合转换成一个只读集合,所以在大数据量分组时性能优于List.大家可以查阅相关资料,这里由于篇幅问题,不再细说。 from:http://www.cnblogs.com/yunfeifei/p/3998783.html

龙生   13 Sep 2016
View Details

5天玩转C#并行和多线程编程 —— 第一天 认识Parallel

随着多核时代的到来,并行开发越来越展示出它的强大威力!使用并行程序,充分的利用系统资源,提高程序的性能。在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threading.Tasks。这里面有很多关于并行开发的东西,今天第一篇就介绍下最基础,最简单的——认识和使用Parallel。   一、 Parallel的使用 在Parallel下面有三个常用的方法invoke,For和ForEach。   1、  Parallel.Invoke 这是最简单,最简洁的将串行的代码并行化。 在这里先讲一个知识点,就是StopWatch的使用,最近有一些人说找不到StopWatch,StopWatch到底是什么东西,今天就来说明一下。 StopWatch在System.Diagnostics命名控件,要使用它就要先引用这个命名空间。 其使用方法如下: var stopWatch = new StopWatch();   //创建一个Stopwatch实例 stopWatch.Start();   //开始计时 stopWatch.Stop();   //停止计时 stopWatch.Reset();  //重置StopWatch stopWatch.Restart(); //重新启动被停止的StopWatch stopWatch.ElapsedMilliseconds //获取stopWatch从开始到现在的时间差,单位是毫秒 本次用到的就这么多知识点,想了解更多关于StopWatch的,去百度一下吧,网上有很多资料。   下面进入整体,开始介绍Parallel.Invoke方法,废话不多说了,首先新建一个控制台程序,添加一个类,代码如下:

代码很简单,首先新加一个类,在类中写了两个方法,Run1和Run2,分别等待一定时间,输出一条信息,然后写了一个测试方法ParallelInvokeMethod,分别用两种方法调用Run1和Run2,然后在main方法中调用,下面来看一下运行时间如何: 大家应该能够猜到,正常调用的话应该是5秒多,而Parallel.Invoke方法调用用了只有3秒,也就是耗时最长的那个方法,可以看出方法是并行执行的,执行效率提高了很多。   2、Parallel.For 这个方法和For循环的功能相似,下面就在类中添加一个方法来测试一下吧。代码如下:

写了两个循环,做了一些没有意义的事情,目的主要是为了消耗CPU时间,同理在main方法中调用,运行结果如下图: 可以看到,Parallel.For所用的时间比单纯的for快了1秒多,可见提升的性能是非常可观的。那么,是不是Parallel.For在任何时候都比for要快呢?答案当然是“不是”,要不然微软还留着for干嘛? 下面修改一下代码,添加一个全局变量num,代码如下:

Parallel.For由于是并行运行的,所以会同时访问全局变量num,为了得到正确的结果,要使用lock,此时来看看运行结果: 是不是大吃一惊啊?Parallel.For竟然用了15秒多,而for跟之前的差不多。这主要是由于并行同时访问全局变量,会出现资源争夺,大多数时间消耗在了资源等待上面。 一直说并行,那么从哪里可以看出来Parallel.For是并行执行的呢?下面来写个测试代码:

从0输出到99,运行后会发现输出的顺序不对,用for顺序肯定是对的,并行同时执行,所以会出现输出顺序不同的情况。   2、Parallel.Foreach 这个方法跟Foreach方法很相似,想具体了解的,可以百度些资料看看,这里就不多说了,下面给出其使用方法:

   二、 Parallel中途退出循环和异常处理 1、当我们使用到Parallel,必然是处理一些比较耗时的操作,当然也很耗CPU和内存,如果我们中途向停止,怎么办呢? 在串行代码中我们break一下就搞定了,但是并行就不是这么简单了,不过没关系,在并行循环的委托参数中提供了一个ParallelLoopState, 该实例提供了Break和Stop方法来帮我们实现。 Break: 当然这个是通知并行计算尽快的退出循环,比如并行计算正在迭代100,那么break后程序还会迭代所有小于100的。 Stop:这个就不一样了,比如正在迭代100突然遇到stop,那它啥也不管了,直接退出。 下面来写一段代码测试一下:

这里使用的是Stop,当数量达到300个时,会立刻停止;可以看到结果"Bag count is 300",如果用break,可能结果是300多个或者300个,大家可以测试一下。   2、异常处理 首先任务是并行计算的,处理过程中可能会产生n多的异常,那么如何来获取到这些异常呢?普通的Exception并不能获取到异常,然而为并行诞生的AggregateExcepation就可以获取到一组异常。 这里我们修改Parallel.Invoke的代码,修改后代码如下:

顺序调用方法我把异常处理写一起了,这样只能捕获Run1的异常信息,大家可以分开写。捕获AggregateException 异常后,用foreach循环遍历输出异常信息,可以看到两个异常信息都显示了。   点击这里,下载源码 from:http://www.cnblogs.com/yunfeifei/p/3993401.html

龙生   13 Sep 2016
View Details

C#中小数点后保留两位小数,四舍五入的函数及使用方法

Math.Round(45.367,2)     //Returns   45.37 Math.Round(45.365,2)     //Returns   45.36 C#中的Round()不是我们中国人理解的四舍五入,是老外的四舍五入,是符合IEEE标准的四舍五入,具体是四舍六入,下面的才是符合中国人理解的四舍五入 Math.Round(45.367,2,MidpointRounding.AwayFromZero);//45.37 Math.Round(45.365,2,MidpointRounding.AwayFromZero)     //Returns   45.37   from:http://www.cnblogs.com/purplefox2008/archive/2011/08/08/2130635.html

龙生   12 Sep 2016
View Details

Asp.net+Mysql,查询出错:由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败

在网上看到的解决方案基本都是说host文件中127.0.0.1 localhost 的对应, 但我查看了host文件,并没有问题,纠结半天,拿查询语句在Mysql Workbench上执行,报了一个错,说是子查询包含多个结果,我去~!这很简单的一个错误asp.net竟然没能准确反馈。 于是在子查询语句后面加limit 1,Ok~ 所以,出现“由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败”这个错误时,有可能是查询语句有问题,而不是连接有问题。 from:http://blog.csdn.net/idoiknow/article/details/8923553

龙生   07 Sep 2016
View Details

NPOI读写Excel

1、整个Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet;行:Row;单元格Cell。 2、NPOI是POI的C#版本,NPOI的行和列的index都是从0开始 3、POI读取Excel有两种格式一个是HSSF,另一个是XSSF。 HSSF和XSSF的区别如下: HSSF is the POI Project’s pure Java implementation of the Excel ’97(-2007) file format. XSSF is the POI Project’s pure Java implementation of the Excel 2007 OOXML (.xlsx) file format. 即:HSSF适用2007以前的版本,XSSF适用2007版本及其以上的。 下面是用NPOI读写Excel的例子:ExcelHelper封装的功能主要是把DataTable中数据写入到Excel中,或者是从Excel读取数据到一个DataTable中。 ExcelHelper类:

测试代码:

Excel相关DLL下载:NPOI-Lib.rar   1.NPOI下载地址:http://npoi.codeplex.com/releases/view/38113 2.NPOI学习系列教程推荐:http://www.cnblogs.com/tonyqus/archive/2009/04/12/1434209.html   参考: http://www.cnblogs.com/Erik_Xu/archive/2012/06/08/2541957.html http://www.cnblogs.com/linzheng/archive/2010/12/20/1912137.html http://www.cnblogs.com/knowledgesea/archive/2012/11/16/2772547.html   from:http://www.cnblogs.com/luxiaoxun/p/3374992.html

龙生   06 Sep 2016
View Details
1 20 21 22 48