假设我有一个这样的方法:
public class MyDataAccess
{
public static StudentDataTable GetStudentRecords(int schoolID)
{
var ta = new StudentTableAdapter();
using (ta.Connection = new SqlConnection(GetCS()))
{
var result = ta.GetStudentRecords(schoolID);
return result;
}
}
}
如果使用控制台应用程序或任何其他方式一次访问此方法1,000次,是否有可能将一个学校的学生的记录返回到另一所学校?
e.g。
var records1 = GetStudentRecords(1);
.....
var records1000 = GetStudentRecords(1000);
records1
变量是否有可能将schoolID = 1
的记录与来自records1000
的记录混合在一起,即使这些记录来自他们自己的主题?
如果我将这个类改为静态会发生什么呢?
此时我的理解
1)是的,我明白课程是什么
2)是的,我知道静态类不需要使用所需的实例
3)我知道应该有简单的静态代码,例如转换数据类型。
但我感到困惑的是:
当存在单个静态类并且有一百万个对象试图访问STACK中的同一个对象时会发生什么
尤其是当它是dataAccess
类或访问activeDirectory
个对象的类时。
我在程序员SE聊天室聊天。他们没有明确说出来,但我得到的印象是从不使用静态类来查询,例如sql,活动目录等。而且静态类应该仅限于简单的静态代码 - 不需要查询。
答案 0 :(得分:5)
查看您给我们的代码,代码似乎是线程安全的。线程之间没有(内存中)数据共享。
我唯一关心的是数据库层 - 确保你使用正确的isolation level来避免脏读。
如果我将此类更改为静态也会发生什么。
关于GetStudentRecords
?什么都没有。
这是线程不安全代码的经典示例。
public class MyDataAccess
{
private static int _retrievalCount = 0;
public static StudentDataTable GetStudentRecords(int schoolID)
{
_retrievalCount ++;
// retrieve and return records;
}
}
字段_retrievalCount
在线程间共享。操作++
不是原子的。也就是说,它涉及三个步骤
_retrievalCount
_retrievalCount
。如果两个线程同时执行此操作,并且这三个步骤是交错的,则可能会发生这种情况(假设_retrievalCount
从0开始并且有2个线程正在运行):
_retrievalCount
读为0 _retrievalCount
读为0 _retrievalCount
_retrievalCount
预期输出为2,但实际输出为1.
答案 1 :(得分:5)
在C#中,“static”仅表示您可以直接从类定义中调用该方法,而不是针对该类的实例调用该方法。
将“类”视为对象的蓝图。创建对象的实例时,蓝图会告诉计算机如何创建它。但是,该类的某些方面不需要实际的对象实例,并且这些方面是通过“静态”方法提供的候选方法。
如果将方法声明更改为包含“static”,则会更改必须调用的方式。
public class Example
{
static void StaticMethod() {...}; // object instance *not* required
void InstanceMethod() {...}; // object instance *is* required
}