当前位置: 首页 > 编程语言 > C#

BeginExecuteNonQuerywithoutEndExecuteNonQueryshare

时间:2023-04-10 21:04:11 C#

BeginExecuteNonQuerywithoutEndExecuteNonQuery我有以下代码:"",sqlConnection)){sqlConnection.Open();command.CommandType=CommandType.StoredProcedure;command.Parameters.AddWithValue("@param1",param1);command.BeginExecuteNonQuery();}}我从不调用EndExecuteNonQuery。两个问题,首先它是因为使用语句还是其他任何原因而阻止它?其次,它会破坏什么吗?像泄漏或连接问题?我只想告诉sqlserver运行存储过程,但我不想等待它,我什至不关心它是否有效。这可能吗?感谢阅读。这不起作用,因为您在查询仍在运行时关闭了连接。执行此操作的最佳方法是使用线程池,如下所示:someProcedureName",sqlConnection)){sqlConnection.Open();command.CommandType=CommandType.StoredProcedure;command.Parameters.AddWithValue("@param1",param1);command.ExecuteNonQuery();}}});通常,当你当Begin_Whatever_被调用时,通常End_Whatever_必须被调用否则你会泄漏内存。这个规则的一个重要例外是Control.BeginInvoke。提交BeginExceuteNotQuery后,连接无法关闭。它会中止执行。删除using块。要关闭connection您必须知道调用何时完成。为此,您必须从回调中正常调用EndExecuteNonQuery:/*记录异常e*/}finally{sqlConnection.Dispose();}},无效的);如果您想提交查询而不关心结果,请参阅异步T-SQL执行以获得可靠模式,即使客户端连接或崩溃也能确保执行...您应该始终调用EndExecuteNonQuery()方法以防止泄漏。它现在可能有效,但谁知道在未来的.NET版本中会发生什么。一般规则始终遵循BeginExecute...与EndExecute...我知道这是一篇旧文章;根据我们最近(非常确定)的实施和测试添加我的2c:D回答OP的问题:如果未调用EndExecuteNonQuery,则BeginExecuteNonQuery将执行该过程,但只要using子句处理sql连接,操作就会被取消。因此,这是不合理的。如果不通过委托调用BeginExecuteNonQuery、创建新线程等方式调用EndExecuteNonQuery,就会因为内存泄漏导致内存泄漏。(稍后会详细介绍)。在我们的测试中,不可能在不等待调用完成的情况下调用存储过程。不管多任务处理,总得在某个地方等待。关于我们的解决方案:参考:BeginExecuteNonQuery->BENQ、EndExecuteNonQuery->EENQ用例:我们有一个使用.NetTPL库的Windows服务(C#)。我们需要在运行时使用基于服务选择的额外请求的存储过程将数据从一个数据库加载到另一个数据库。我们的存储过程使用trycatch块进行内部事务和异常处理。第一次尝试:对于我们的第一次尝试,我们在这个例子中实现了一个解决方案。在这个例子中,你会看到MS选择调用BENQ,然后实现一个while循环来阻止执行,然后调用EENQ。如果您不需要回调方法,则主要实施此解决方案。这个解决方案的问题是只有BENQ不知道sql连接超时。EENQ将超时。因此,对于长时间运行的查询(希望这就是您使用BENQ的原因),您将被卡住,一旦操作完成并调用EENQ,您将获得一个sql超时连接。第二次尝试:对于我们的第二次尝试,我们认为可以,所以我们调用了BENQ,然后添加了一个句点,这样我们就不会关闭我们的sql连接并且永远不会调用EENQ。这一直有效,直到在我们的存储过程中抛出异常。因为我们从未调用过EENQ,所以操作从未完成,并且异常也从未冒充过我们的代码。所以我们永远陷入循环/线程/内存泄漏。第三次尝试:(解决方案)对于我们的第三次尝试,我们将调用BENQ,然后直接调用EENQ。发生的情况是EENQ有效地阻止了线程中的执行,直到操作完成。当存储过程中发生异常时,它会被捕获。当查询运行很长时间时,EENQ没有抛出超时异常,并且在所有情况下,我们的sql连接对象都从我们的线程中释放出来。以下是我们代码的一些摘录:这里我们为调用存储过程的方法打开了一个新线程。//调用加载数据存储过程。由于这个存储过程可以运行更长时间,我们在它自己的线程中启动它。Task.Factory.StartNew(()=>ClassName.MethodName(Parameters));方法中的代码。//因为这是一个长时间运行的存储过程,所以我们在一个新线程中启动。using(SqlConnectionconn=newSqlConnection(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["ConnectionStringName"]].ConnectionString)){try{//创建一个新实例SqlCommand。SqlCommand命令=newSqlCommand(ConfigurationManager.AppSettings["StoredProcedureName"],conn);//设置命令类型为存储过程。command.CommandType=CommandType.StoredProcedure;//创建输入参数。command.Parameters.Add(CreateInputParam("@Param1",SqlDbType.BigInt,Param1));command.Parameters.Add(CreateInputParam("@Param2",SqlDbType.BigInt,Param3));command.Parameters.Add(CreateInputParam("@Param3",SqlDbType.BigInt,Param3));//打开sql连接。conn.Open();//创建一个IAsyncResult类型的新实例并异步调用sp。IAsyncResult结果=command.BeginExecuteNonQuery();//当过程完成时,我们结束sp的执行。命令.EndExecuteNonQuery(结果);}catch(Exceptionerr){//写入日志。我希望这个答案可以解决这个问题:D我们已经彻底测试了这个问题并且它没有遇到任何问题的快乐编码!在这种情况下,using语句不是必需的,因为您应该自己手动关闭它,而不是让语法糖为您处理它(即在}中)。应该很简单,以确保您没有泄漏。using(SqlConnectionsqlConnection=newSqlConnection("blahblah;AsynchronousProcessing=true;"){using(SqlCommandcommand=newSqlCommand("someProcedureName",sqlConnection)){sqlConnection.Open();command.CommandType=CommandType.StoredProcedure;命令.Parameters.AddWithValue("@param1",param1);command.BeginExecuteNonQuery((ar)=>{varcmd=(SqlCommand)ar.AsyncState;cmd.EndExecuteNonQuery(AR);cmd.Connection.Close();},command);}}如您所见,在命令完成后触发的lambda表达式(无论需要多长时间)都会为您完成所有关闭操作。以上就是C#学习教程:没有EndExecuteNonQuery的BeginExecuteNonQuery分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: