使用陈述问题
我有两个问题。
1) 是否应该始终在连接上使用 using 语句?那么,我会在连接上使用它,然后在连接内的阅读器上使用另一个吗?所以我会使用两个 using 语句。
2) 假设您在连接上使用 using 语句,并且在连接上返回了一个读取器。所以你有两个 using 语句。它会创建两个 Try{}Finally{} 块还是仅创建一个?
谢谢!
I have two questions.
1) Should you always use a using statement on a connection? So, I would use it on the connection and then another one on a reader within the connection? So I would be using two using statements.
2) Lets say you use the using statement on the connection and also a reader being returned on the connection. So you have two using statements. Does it create two Try{}Finally{} blocks or just one?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这里要小心。您应该始终在任何实现IDisposable的本地对象上使用语句。这不仅包括连接和读者,还包括命令。但有时 using 语句的具体位置可能会很棘手。如果您不小心,可能会导致问题。例如,在 using 语句后面的代码中,将在您使用它之前关闭您的阅读器:
相反,您有四个选项。一种是等待创建 using 块,直到调用该函数:
当然,您仍然必须小心那里的连接,这意味着记住在使用该函数的任何地方都编写一个 using 块。
选项二只是在方法本身中处理查询结果,但这会破坏数据层与程序其余部分的分离。第三个选项是让 MyQuery() 函数接受 Action 类型的参数,您可以在 while (rdr.Read()) 循环内调用该参数,但这很尴尬。
我通常更喜欢选项四:将数据读取器变成 IEnumerable,如下所示:
现在所有内容都将正确关闭,并且处理它的代码都在一个位置。您还可以获得一个不错的好处:您的查询结果将与任何 linq 运算符一起良好地工作。
最后,我下次要构建一个全新的项目,将 IEnumerable 与传入委托参数相结合,这是我要玩的新东西:
然后我将在数据层中使用它,如下所示:
Be careful here. You should always have a using statement on any local object that implements IDisposable. That includes not only connections and readers, but also the command. But it can be tricky sometimes exactly where that using statement goes. If you're not careful it can cause problems. For example, in the code that follows the using statement will close your reader before you ever get to use it:
Instead, you have four options. One is to wait to create the using block until you call the function:
Of course, you still have to careful with your connection there and it means remember to write a using block everywhere you use the function.
Option two is just process the query results in the method itself, but that breaks separation of your data layer from the rest of the program. A third option is for your MyQuery() function to accept an argument of type Action that you can call inside the while (rdr.Read()) loop, but that's just awkward.
I generally prefer option four: turn the data reader into an IEnumerable, like this:
Now everything will be closed correctly, and the code that handles it is all in one place. You also get a nice bonus: your query results will work well with any of the linq operators.
Finally, something new I'm playing with for the next time I get to build a completely new project that combines the IEnumerable with passing in a delegate argument:
And then I'll use it within the data layer like this:
是的,因为他们实现了
IDisposable
。并且不要忘记命令上的using
语句:每个
using
语句都会创建自己的try/finally
块Yes, because they implement
IDisposable
. And don't forget ausing
statement on the command too :Each
using
statement will create its owntry/finally
block当对象实现
IDisposable
时,您应该始终使用using
语句。这包括连接。它将创建两个嵌套的
try{}finally{}
块。You should always use a
using
statement when an object implementsIDisposable
. This includes connections.It will create two nested
try{}finally{}
blocks.特别说明1)。当在 异步 ADO.NET 方法 - 类似于 BeginExecuteReader,因为您很可能会超出范围并在异步操作仍在进行时尝试释放连接。这与使用类变量而不是局部变量时的情况类似。通常,连接引用存储在用作异步操作的“控制块”的类中。
Special point on 1). You need to specifically avoid that technique when the connection is used in asynchronous ADO.NET methods - like BeginExecuteReader, because more than likely, you will fall out of scope and try to dispose the connection while the async operation is still in progress. This is similar to the case when you are using class variables and not local variables. Often times the connection reference is stored in a class used as the "control block" for the asynchronous operation.
回答每个问题:
1)是的,最好的做法是尽快处理掉这两个问题。
2)
using()
将创建两个块,以相同的顺序相互包裹。它将首先处理内部对象(读取器),然后使用外部对象(连接)处理对象。To answer each one:
1) Yes, this would be best practice to dispose both as soon as possible.
2)
using()
will create two blocks, wrapped in each other in the same order. It will dispose the inner object (the reader) first, then dispose the object from the outer using (the connection).