2012-12-11 50 views
3

好的簡單的問題。在下面的類中,returnAttackDescription函數線程安全。ASP.net靜態DataView使用橫跨整個訪客 - 公共靜態函數 - 這種方式線程安全嗎?

我的意思是假定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

第二種可能的解決方案加入 – MonsterMMORPG

回答

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;,只有當您的應用程序啓動後纔會創建該參數 - 之後您只能讀取內容......但是您不能在內部使用外部鎖定來更改它。

不同一至兩的是,在第一內側與過濾器中的數據變化,第二你只是閱讀並複製你需要新的記憶之一,所以你只能讀取它們。第二個原樣。

並將此數據視圖獲得的第一個函數調用

其初始化的時刻在應用程序啓動之前的任何頁面調用初始化。您可以使用Debug.Write來檢查這一點。

+0

第二種解決方案如何?數據將始終保持不變,因爲它在重新啓動時不會更改。你更喜歡哪一個? – MonsterMMORPG

+0

@MonsterMMORPG我不知道我喜歡什麼 - 也許把它們放在適當的時間看看什麼更快,並選擇更快的。我認爲第一個更快。您可以使用'Debug.Write()'來查看定時的工作方式 - 例如調用「Descriptions()」。 – Aristos

+0

當行過濾DataView狀態正在改變。這實際上讓我感到困惑。因爲許多線程使行篩選器如何獲得單個結果? – MonsterMMORPG