我想创建一个存储数据表的类,这将阻止我的应用程序在每次检索时导入详细信息列表.因此这应该做一次,我相信下面的代码会这样做,但我不确定它是否是线程安全的.

下面的代码位于我的三层应用程序的业务层部分,它将数据表返回到表示层.

public class BusinessLayerHandler
{
    public static DataTable unitTable;
    public static DataTable currencyTable;

    public static DataTable GetUnitList()
    {
        //import lists each time the application is run
        unitTable = null;
        if (unitTable == null)
        {
            return unitTable = DatabaseHandler.GetUnitList();
        }
        else
        {
            return unitTable;
        }
    }

    public static DataTable GetCurrencyList()
    {
        //import lists each time the application is run
        currencyTable = null;
        if (currencyTable == null)
        {
            return currencyTable = DatabaseHandler.GetCurrencyList();
        }
        else
        {
            return currencyTable;
        }
    }

感谢任何帮助,如果有更好的方式缓存数据表,请让我知道.

更新:

多亏了你的意见,如果我理解正确,这是建议的方法:

public class BusinessLayerHandler
{
    private static DataTable unitTable;
    private static DataTable currencyTable;

    private static readonly object unitTableLock = new object();
    private static readonly object currencyTableLock = new object();

    public static DataTable GetUnitList()
    {
        //import lists each time the application is run
        //unitTable = null;

        lock (unitTableLock)
        {
            if (unitTable == null)   
            {
                return unitTable = DatabaseHandler.GetUnitList();
            }
        }
        return unitTable;
    }

    public static DataTable GetCurrencyList()
    {
        //import lists each time the application is run
        lock (currencyTableLock)
        {
            if (currencyTable == null)
            {
                return currencyTable = DatabaseHandler.GetCurrencyList();
            }
        }
        return currencyTable;
    }
}

推荐答案

看起来好像你只想加载一次并保留对它的引用.如果变量为null,则只需初始化它.空值判断、锁定和再次空值判断被称为Double Check Locking,对您很有效.最好的做法是提供一个单独的锁对象,这样就可以很好地控制锁的粒度.

注意,这并不能阻止人们改变DataTable中的值,它只会阻止人们同时try 初始化静态成员.

private static readonly object UnitTableLock = new object();
private static DataTable unitTable;
private static bool _ready = false;

public static DataTable GetUnitList()
{
    if (!_ready)
    {
        lock (UnitTableLock)
        {
            if (!_ready)
            {
                unitTable = new DataTable; //... etc
                System.Threading.Thread.MemoryBarrier();
                _ready = true;
            }
        }
    }

    return unitTable;
}

只能从结果GetUnitList中读取,决不能写入.

参照第http://en.wikipedia.org/wiki/Double-checked_locking条修订

Asp.net相关问答推荐

无法在Microsoft Windows Server 2016(数据中心)上运行.NET可移植性分析器

分层架构中的 ASP.NET 和实体框架 - 仅将实体框架用于 ORM

某些黑客能否从用户那里窃取 Web 浏览器 cookie 并在网站上使用该名称登录?

在 Asp.net 中通过 Button 的 CommandArgument 传递多个参数

从 GUID 中删除破折号是个好主意吗?

忽略默认文档的表单身份验证

如何在同一解决方案中从 MVC 项目调试 Web API 项目

ASP.NET RadioButton 与名称(组名)混淆

使用 LINQ 进行递归控制搜索

如何使用 ASP.NET 和 jQuery 返回 JSON

<%# Eval("State") %> 或 <%# DataBinder.Eval(Container.DataItem, "state")%>

通过 ASP.NET/C# 使用 Plupload

要调用此方法,Membership.Provider属性必须是ExtendedMembershipProvider的实例

.NET 4.0 中的自定义 MembershipProvider

在 C# 中动态创建 Json

在 ASPNET 标识 2.0 中禁用用户

System.Linq.IQueryable 不包含Where的定义

从服务器下载 ASP.NET 文件

如何使用 WebAPI 处理图像

您的下一个 ASP.NET 项目的 Select 是什么:Web 窗体还是 MVC?