C#静态方法问题

标签 c# sql multithreading

我不明白在多线程环境中使用带有静态成员的静态类时幕后到底发生了什么。 我有一个服务器应用程序,客户端经常读写 SQL 数据库。为此,我创建了具有静态成员 SQLConnection、SLQDataReader 等的静态类。但据我了解,静态类只是一个,在线程之间共享,那么它如何同时处理多个请求?只使用非静态类会不会更好? 谢谢!

最佳答案

我将与其他答案不同,并说将 SqlConnection 尤其是 SqlDataReader 作为全局状态是一个非常糟糕的主意。这是一种巨大的设计气味。需要考虑的几个问题:

  • 连接会一直保持打开状态吗?如果是这样 - 您是否知道这会浪费数据库服务器上的资源,甚至可能导致您超过许可连接数?

  • 如果连接不会保持打开状态 - 您将采取什么步骤来防止一个线程关闭连接而另一个线程正在使用的情况?事实上,您的代码甚至不一定需要多线程才能发生这种情况;为了防止这种情况,每次对数据库的操作都要先保存原来的连接状态,如果关闭就打开连接,完成后再恢复原来的状态。

  • 您是否正在序列化对 SqlConnection 的访问?如果是这样,您是否会在整个数据库操作期间锁定它,这会导致大量不必要的等待时间,从而严重影响整体应用性能?

  • 如果您没有序列化访问,当一个操作试图执行一些不相关的操作而另一个操作正在进行重要事务时会发生什么情况?

  • 如果制作一个“全局”SqlDataReader,您能否绝对确定一次只有一个线程会使用它,并且该线程永远不需要在它之前执行另一个查询第一个结果集完成了吗?即使 SqlDataReader 是线程安全的(事实并非如此),如果您实际上销毁了相关对象并将其替换为新对象,则线程安全规则将失效。

SqlConnection 确实应该被视为一个工作单元 - 您在需要时创建它,并在完成时处理它。 SqlDataReader 甚至不是一个工作单元 - 它是一个一次性对象,绝对没有理由将其保留在全局级别。即使您像其他人显然建议的那样实现单例,您以后也会遇到很多麻烦。

更新:如果这些“成员”实际上是工厂方法,那就不一样了。问题的措辞方式暗示实际上共享了一个连接。如果您只是提供静态方法来创建 连接/查询,那么您可以忽略它。

关于C#静态方法问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1995067/

相关文章:

multithreading - Delphi 在线程中搜索文件

python - 覆盖python threading.Thread.run()

c# - 当客户端花费超过 60 秒来确认消息时,Rabbitmq 服务器断开连接

c# - 如何从 ASP.NET 向导中的动态输入和步骤中收集值

sql - 获取 SQL Server 中触发器的调用者

c# - 将 Linq to Sql 查询转换为更好的 sql

c++ - RH Linux 互斥锁调试

c# - C# 中的 Google Geocoding Json 解析问题

c# - 在 C# 中创建弹出窗体

c# - 像 GlovePIE 一样伪造输入