[英]ASP.net static DataView usage accross entire visitors - public static function - is this way thread safe?
好的問題。 在下面的類中執行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
解決方案不是真正的線程安全,我現在看到的問題是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 dvAttacks
更改,直到應用程序重新啟動。 應用程序的每個池都有一組不同的數據。
在第二個解決方案中,您只讀取它們而不影響DataView
,因此您不要將它們更改為有任何沖突。 就這樣,工作得很好,並且所有新內存都沒有在線程上發生沖突。
這是常見的private static DataView dvAttacks;
的參數private static DataView dvAttacks;
在線程之間,這僅在您的應用程序啟動時創建 - 之后您只讀取...但您不能將其更改為內部以及鎖定。
一到兩個之間的區別在於,第一個數據在內部使用過濾器進行更改,在第二個文檔中,您只需讀取它們並在新內存中復制所需的數據,因此您只能讀取它們。 第二個工作原樣。
並將在第一次函數調用時初始化此數據視圖
它在應用程序啟動時和任何頁面調用之前初始化。 您可以使用Debug.Write
來檢查它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.