C# 正确的类定义和用法-线程安全-ASP.net
我想知道如何正确定义一个类并安全地使用它。我的意思是,当每个网站访问者同时拨打数千个电话时,线程是安全的 我给自己做了一个像下面这样的东西,但我想知道它是否正确建造C# 正确的类定义和用法-线程安全-ASP.net,c#,asp.net,c#-4.0,thread-safety,static-functions,C#,Asp.net,C# 4.0,Thread Safety,Static Functions,我想知道如何正确定义一个类并安全地使用它。我的意思是,当每个网站访问者同时拨打数千个电话时,线程是安全的 我给自己做了一个像下面这样的东西,但我想知道它是否正确建造 public static class csPublicFunctions { private static Dictionary<string, clsUserTitles> dicAuthorities; static csPublicFunctions() { dicAut
public static class csPublicFunctions
{
private static Dictionary<string, clsUserTitles> dicAuthorities;
static csPublicFunctions()
{
dicAuthorities = new Dictionary<string, clsUserTitles>();
using (DataTable dtTemp = DbConnection.db_Select_DataTable("select * from myTable"))
{
foreach (DataRow drw in dtTemp.Rows)
{
clsUserTitles tempCLS = new clsUserTitles();
tempCLS.irAuthorityLevel = Int32.Parse(drw["Level"].ToString());
tempCLS.srTitle_tr = drw["Title_tr"].ToString();
tempCLS.srTitle_en = drw["Title_en"].ToString();
dicAuthorities.Add(drw["authorityLevel"].ToString(), tempCLS);
}
}
}
public class clsUserTitles
{
private string Title_tr;
public string srTitle_tr
{
get { return Title_tr; }
set { Title_tr = value; }
}
private string Title_en;
public string srTitle_en
{
get { return Title_en; }
set { Title_en = value; }
}
private int AuthorityLevel;
public int irAuthorityLevel
{
get { return AuthorityLevel; }
set { AuthorityLevel = value; }
}
}
public static clsUserTitles returnUserTitles(string srUserAuthority)
{
return dicAuthorities[srUserAuthority];
}
}
公共静态类csPublicFunctions
{
私有静态字典权限;
静态csPublicFunctions()
{
diauthorities=新字典();
使用(DataTable dtTemp=DbConnection.db\u Select\u DataTable(“Select*from myTable”))
{
foreach(数据行中的数据行drw)
{
clsUserTitles tempCLS=新clsUserTitles();
tempCLS.irAuthorityLevel=Int32.Parse(drw[“Level”].ToString());
tempCLS.srTitle_tr=drw[“Title_tr”].ToString();
tempCLS.srTitle_en=drw[“Title_en”].ToString();
添加(drw[“authorityLevel”].ToString(),tempCLS);
}
}
}
公共类许可证
{
私有字符串标题;
公共字符串sru-tr
{
获取{return Title_tr;}
设置{Title_tr=value;}
}
私有字符串标题;
公共字符串sru-en
{
获取{return Title_en;}
设置{Title_en=value;}
}
私人int AuthorityLevel;
公共内部irAuthorityLevel
{
获取{return AuthorityLevel;}
设置{AuthorityLevel=value;}
}
}
公共静态clsUserTitles returnUserTitles(字符串srUserAuthority)
{
返回diauthorities[srUserAuthority];
}
}
字典将仅初始化一次。以后不再添加或删除更新。快速查看您的代码,在我看来,您的第一个问题将是公开可用的词典
diauthorities
。字典不是线程安全的。根据您想对该词典做什么,您需要实现一些规范对其访问的功能。见这一相关问题:
您的问题的答案是否定的,它不是线程安全的<代码>字典不是线程安全的集合。如果要使用线程安全字典,请使用
除此之外,很难说您的
csPublicFunctions
是否是线程安全的,因为这取决于您在调用DbConnection.db\u Select\u DataTable
字典时如何处理数据库连接。以下是来自以下方面的证据:
一本词典可以同时支持多个读者,
只要集合未被修改。即便如此,列举
通过集合本质上不是线程安全的过程。在里面
枚举与写访问争用的罕见情况是
在整个枚举过程中必须锁定集合。允许
要由多个线程访问以进行读写的集合,
您必须实现自己的同步
因此,如果您计划只从中读取数据,它应该可以工作。然而,我不相信你的字典只填写了一次,也不会在你的申请工作中被修改。在这种情况下,该线程中的所有其他人都是正确的,有必要同步对该字典的访问,最好使用该对象
现在,我想就设计本身说几句话。如果要在用户之间存储共享数据,请使用专门为此目的而设计的。正如其他人所说,
字典本身并不是线程安全的。但是,如果您的使用场景是:
启动时填写字典
在应用程序运行时将该字典用作查找
切勿在启动后添加或删除值
你应该会没事的
但是,如果您使用.NET4.5,我建议使用
因此,您的实现可能是这样的(将编码样式更改为更为C#友好)
私有静态只读只读复制权限;
静态公共函数()
{
Dictionary authoritiesFill=新建字典();
使用(DataTable dtTemp=DbConnection.db\u Select\u DataTable(“Select*from myTable”))
{
foreach(数据行中的数据行drw)
{
UserTitles userTitle=新的UserTitles
{
AuthorityLevel=Int32.Parse(drw[“Level”].ToString()),
TitleTurkish=drw[“Title_tr”].ToString();
TitleEnglish=drw[“Title_en”]。ToString();
}
authoritiesFill.Add(drw[“authorityLevel”].ToString(),userTitle);
}
}
权限=新的只读词典(authoritiesFill);
}
我还向声明本身添加了一个只读
修饰符,因为这样可以确保它在运行时不会被另一个字典替换。只有public字典
没有线程安全问题。
是的,字典填充是线程安全的。但是这本字典的另一个修改是线程安全的。如上所述,ConcurrentDictionary
可能会有所帮助
另一个问题是类clsuertitles
也不是线程安全的。
如果clsuertitles
仅用于读取,则可以将clsurtitles
的每个属性设置器设置为私有。并从clsuertitles
构造函数初始化这些属性。不,您的代码不是线程安全的
- [编辑不适用-在静态构造函数内设置/创建]字典(如系统关闭答案所指出的)在更新时不是线程安全的。字典不是只读的,因此无法保证它不会随着时间的推移而被修改
- [编辑不适用-在静态构造函数内设置/创建]初始化不受任何锁的保护,因此最终会在
private static readonly ReadOnlyDictionary<string, UserTitles> authorities;
static PublicFunctions()
{
Dictionary<string, UserTitles> authoritiesFill = new Dictionary<string, clsUserTitles>();
using (DataTable dtTemp = DbConnection.db_Select_DataTable("select * from myTable"))
{
foreach (DataRow drw in dtTemp.Rows)
{
UserTitles userTitle = new UserTitles
{
AuthorityLevel = Int32.Parse(drw["Level"].ToString()),
TitleTurkish = drw["Title_tr"].ToString();
TitleEnglish = drw["Title_en"].ToString();
}
authoritiesFill.Add(drw["authorityLevel"].ToString(), userTitle);
}
}
authorities = new ReadOnlyDictionary<string, UserTitles>(authoritiesFill);
}