好的简单问题。在下面的类中执行returnAttackDescription函数线程安全。
我的意思是假设使用所有不同的参数同时对该函数进行100次不同的调用(因为它需要3个参数)
这项工作线程安全吗?如果不是我怎么能让它的线程安全?这个数据视图会在第一次函数调用时初始化吗?还是什么时候?
谢谢
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
public static class Descriptions
{
private static DataView dvAttacks;
static Descriptions()
{
try
{
DataSet dsTempEnemyAttack = DbConnection.db_Select_Query("select AttackType,AttackCategory,BasePower,Accuracy,MoreFacts_tr,MoreFacts_en,Priority from tblAttacks");
dvAttacks = new DataView(dsTempEnemyAttack.Tables[0]);
}
catch
{
}
}
public static string returnAttackDescription(string srAttackName, string srLang, string srCssClassName)
{
dvAttacks.RowFilter = "AttackName='" + srAttackName + "'";
string srReturn = string.Format("<div class=\"{0}\" title=\"" +
"{0}<hr/>" +
"Type: {1}<br/>" +
"Category: {2}<br/>" +
"Base Power: {3}<br/>" +
"Accuracy: {4}<br/>" +
"Priority: {5}<br/>" +
"Effect: {6}\"></div>", srCssClassName, srAttackName,
dvAttacks[0]["AttackType"].ToString(),
dvAttacks[0]["AttackCategory"].ToString(),
dvAttacks[0]["BasePower"].ToString(),
dvAttacks[0]["Accuracy"].ToString(),
dvAttacks[0]["Priority"].ToString(),
dvAttacks[0]["MoreFacts_" + srLang].ToString());
return srReturn;
}
}
第二种可能的解决方案是这个线程安全吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
public static class Descriptions
{
private static DataView dvAttacks;
static Descriptions()
{
try
{
dsAttacks = DbConnection.db_Select_Query("select AttackName,AttackType,AttackCategory,BasePower,Accuracy,MoreFacts_tr,MoreFacts_en,Priority from tblAttacks");
}
catch
{
}
}
public static string returnAttackDescription2(string srAttackName, string srLang, string srCssClassName)
{
var results = (from r in dsAttacks.Tables[0].AsEnumerable()
where r.Field<string>("AttackName") == srAttackName
select new
{
srAttackType = r.Field<string>("AttackType"),
srAttackCategory = r.Field<string>("AttackCategory"),
irBasePower = r.Field<Int16>("BasePower"),
irAccuracy = r.Field<Int16>("Accuracy"),
irPriority = r.Field<Int16>("Priority"),
srMoreFacts = r.Field<string>("MoreFacts_" + srLang)
}
).FirstOrDefault();
string srReturn = string.Format("<div class=\"{0}\" title=\"" +
"{0}<hr/>" +
"Type: {1}<br/>" +
"Category: {2}<br/>" +
"Base Power: {3}<br/>" +
"Accuracy: {4}<br/>" +
"Priority: {5}<br/>" +
"Effect: {6}\"></div>", srCssClassName, srAttackName,
results.srAttackType,
results.srAttackCategory,
results.irBasePower,
results.irAccuracy,
results.irPriority, results.srMoreFacts);
return srReturn;
}
}
c#asp.net 4.0
答案 0 :(得分:1)
解决方案不是实际线程安全的,我现在看到的问题是dvAttacks.RowFilter
会改变结果,所以你需要通过使用线程锁来使其线程安全:
private static readonly object _lock = new object();
public static string returnAttackDescription(string srAttackName, string srLang, string srCssClassName)
{
lock (_lock)
{
dvAttacks.RowFilter = "AttackName='" + srAttackName + "'";
string srReturn = string.Format("<div class=\"{0}\" title=\"" +
"{0}<hr/>" +
"Type: {1}<br/>" +
"Category: {2}<br/>" +
"Base Power: {3}<br/>" +
"Accuracy: {4}<br/>" +
"Priority: {5}<br/>" +
"Effect: {6}\"></div>", srCssClassName, srAttackName,
dvAttacks[0]["AttackType"].ToString(),
dvAttacks[0]["AttackCategory"].ToString(),
dvAttacks[0]["BasePower"].ToString(),
dvAttacks[0]["Accuracy"].ToString(),
dvAttacks[0]["Priority"].ToString(),
dvAttacks[0]["MoreFacts_" + srLang].ToString());
return srReturn;
}
}
当您的应用程序启动时调用函数Descriptions()
,生成静态数据DataView dvAttacks
,然后这些数据保留在内存中,不会发生变化,直到应用程序重新启动。您的应用程序的每个池都有一组不同的数据。
在第二个解决方案中,您只读取它们而不影响DataView
,因此您不要将它们更改为有任何冲突。就这样,工作得很好,并且所有新内存都没有在线程上发生冲突。
这是线程中常见的private static DataView dvAttacks;
参数,这只是在您的应用程序启动时创建的 - 之后您只读取了...但是您不能将其更改为内部以及锁定。< / p>
一和二之间的区别在于,第一个数据在内部使用过滤器进行更改,在第二个文件中,您只需读取它们并在新内存中复制所需的数据,因此您只能读取它们。第二个工作原样。
将在第一次函数调用时初始化此数据视图
在应用程序启动时和任何页面调用之前初始化。您可以使用Debug.Write
进行检查。