繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM