2012-12-11 22 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