ASP.net静态DataView使用遍及整个访问者 - 公共静态函数 - 这种方式线程安全吗?

时间:2012-12-11 21:06:29

标签: c# asp.net function static thread-safety

好的简单问题。在下面的类中执行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

1 个答案:

答案 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进行检查。