如何构建 C# 控制台应用程序以有效使用 IDisposable 数据库资源?
这是我建议的 C# 控制台应用程序设计(非常简化以说明问题空间)。 数据库连接实现 IDisposable,并且此解决方案不允许使用
数据库连接对象。 有人可以为控制台应用程序提出更正确的结构吗? 这是我经常需要解决的问题。
class Program
{
SQLiteConnection sourceConnection;
SQLiteConnection destinationConnection;
static void Main(string[] args)
{
Program shell = new Program();
// get connection strings from command line arguments
string sourceConnectionString = shell.getConnectionString(args);
string destinationConnectionString = shell.getConnectionString(args);
// call non-static methods that use
shell.setUpConnections(sourceConnectionString, destinationConnectionString);
shell.doDatabaseWork();
}
private void setUpConnections(string sourceConnectionString, string destinationConnectionString)
{
sourceConnection = new SQLiteConnection(sourceConnectionString);
destinationConnection = new SQLiteConnection(destinationConnectionString);
}
private void doDatabaseWork()
{
// use the connections here
}
}
编辑:
有些人不明白为什么我希望它们作为成员变量。 这是我的用例(有点伪编码),说明了 doDatabaseWork 中的内容:
foreach (Row sourceRow in DBResultSet)
{
string sourceXml = sourceRow.Columns["MyColumnName"].Value;
string destinationXML = transformUsingXSLT(sourceXml);
writeToDestination(destinationXml);
}
看看我希望如何在此循环的生命周期中保持这些连接打开?
Here's my proposed (very simplified to illustrate the problem space) design for a C# console application. The database connections implement IDisposable, and this solution doesn't allow for using
the database connection objects. Can someone propose a more correct structure for a console application? This is a problem I need to solve often.
class Program
{
SQLiteConnection sourceConnection;
SQLiteConnection destinationConnection;
static void Main(string[] args)
{
Program shell = new Program();
// get connection strings from command line arguments
string sourceConnectionString = shell.getConnectionString(args);
string destinationConnectionString = shell.getConnectionString(args);
// call non-static methods that use
shell.setUpConnections(sourceConnectionString, destinationConnectionString);
shell.doDatabaseWork();
}
private void setUpConnections(string sourceConnectionString, string destinationConnectionString)
{
sourceConnection = new SQLiteConnection(sourceConnectionString);
destinationConnection = new SQLiteConnection(destinationConnectionString);
}
private void doDatabaseWork()
{
// use the connections here
}
}
Edit:
Some people can't figure out why I'd want them as member variables. Here's my use case (a little psuedocoded) of what would go in doDatabaseWork:
foreach (Row sourceRow in DBResultSet)
{
string sourceXml = sourceRow.Columns["MyColumnName"].Value;
string destinationXML = transformUsingXSLT(sourceXml);
writeToDestination(destinationXml);
}
See how I'd want to keep these connections open for the life of this loop?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
编写一个实现 IDisposable 的类怎么样?
在类构造函数中,您可以实例化数据库连接。
然后在 IDisposable.Dispose 方法中,编写用于关闭数据库连接的拆卸代码。
这是一个代码示例来演示我的意思:
然后,从 Program 类的 main 方法中:
How about writing a class that implements IDisposable.
Inside your class constructor, you can instantiate your DB connections.
Then inside your IDisposable.Dispose Method, you write your tear down code for closing your DB connections.
Here is a code sample to demonstrate what I mean:
And then, from within your main method of your Program class:
我认为最好的解决方案是从 Program 类中提取主要逻辑。 Program 类是主要工作的某种启动器。 为 SqlConnections 提供包装器确实不是一个好主意,因为它们已经是托管资源,包装它们是多余的。 因此我的解决方案如下所示:
I think that the best solution is to extract main logic from Program class. The Program class is some kind of starter for primary work. And providing wrappers for SqlConnections is not a good idea indeed, because they are managed resources already, wrapping them is redundant. Thus my solution looks like this:
斯科特的回答是一种方法。 您也可以考虑使用 try{} finally 来代替?
Scott's answer is one way to do it. You could also consider using try{} finally instead?
就我个人而言,我认为您对此想得太多了,并且该线程中的代码示例过于复杂。 我不知道为什么人们在他们的 Program 类上实现 IDisposable ,因为它在退出时就被释放了。
我想不出有什么不使用或不能使用 using(){} 语句的理由。
您想打开一个连接并保持它吗? 为什么? 所有真正的连接都在 .net 连接池的幕后,因此新建 Connection 对象并不是什么大问题。 只需根据需要打开和关闭它们,连接池就会在幕后处理所有这些事情。
我编辑了我的示例,将其包装在一个类中,以便您也可以进行封装。
Personally, I think you are over thinking this and the code samples in this thread are overly complex imho. I have no idea why people are implementing IDisposable on their Program class either since it's disposed when it exits.
I can't think of a single reason to not use or why you cannot use the using(){} statement.
You want to open a Connection and hold it? Why? All the real connections are behind the scenes in .net connection pooling, so new'ing Connection objects is not a big deal. Just open and close as you need them and connection pooling handles all that behind the scenes.
I edited my example to wrap it in a class so you can have your encapsulation as well.
嗯,我发现没有人提到这样做。 您不必在本地声明
using
中使用的变量。Hmm, I see no one has mentioned doing it this way. You don't have to have the variables that are used in the
using
declared locally.