在 ASP.NET 中正确执行锁定

2023-11-22

我有一个 ASP.NET 站点,其搜索功能相当慢,我想通过使用查询作为缓存键将结果添加到缓存一小时来提高性能:

using System;
using System.Web;
using System.Web.Caching;

public class Search
{
    private static object _cacheLock = new object();

    public static string DoSearch(string query)
    {
        string results = "";

        if (HttpContext.Current.Cache[query] == null)
        {
            lock (_cacheLock)
            {
                if (HttpContext.Current.Cache[query] == null)
                {
                    results = GetResultsFromSlowDb(query);

                    HttpContext.Current.Cache.Add(query, results, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
                }
                else
                {
                    results = HttpContext.Current.Cache[query].ToString();
                }
            }
        }
        else
        {
            results = HttpContext.Current.Cache[query].ToString();
        }

        return results;
    }

    private static string GetResultsFromSlowDb(string query)
    {
        return "Hello World!";
    }
}

假设访客 A 进行了搜索。缓存为空,设置锁并向数据库请求结果。现在,访问者 B 进行了不同的搜索:访问者 B 是否必须等待访问者 A 的搜索完成?我真正想要的是 B 立即调用数据库,因为结果会有所不同,并且数据库可以处理多个请求 - 我只是不想重复昂贵的不必要的查询。

对于这种情况,正确的方法是什么?


除非您绝对确定没有冗余查询至关重要,否则我会完全避免锁定。 ASP.NET 缓存本质上是线程安全的,因此以下代码的唯一缺点是,当关联的缓存条目过期时,您可能会暂时看到一些冗余查询相互竞争:

public static string DoSearch(string query)
{
    var results = (string)HttpContext.Current.Cache[query];
    if (results == null)
    {
        results = GetResultsFromSlowDb(query);

        HttpContext.Current.Cache.Insert(query, results, null,
            DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
    }
    return results;
}

如果您决定确实必须避免所有冗余查询,那么您可以使用一组更细粒度的锁,每个查询一个锁:

public static string DoSearch(string query)
{
    var results = (string)HttpContext.Current.Cache[query];
    if (results == null)
    {
        object miniLock = _miniLocks.GetOrAdd(query, k => new object());
        lock (miniLock)
        {
            results = (string)HttpContext.Current.Cache[query];
            if (results == null)
            {
                results = GetResultsFromSlowDb(query);

                HttpContext.Current.Cache.Insert(query, results, null,
                    DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
            }

            object temp;
            if (_miniLocks.TryGetValue(query, out temp) && (temp == miniLock))
                _miniLocks.TryRemove(query);
        }
    }
    return results;
}

private static readonly ConcurrentDictionary<string, object> _miniLocks =
                                  new ConcurrentDictionary<string, object>();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 ASP.NET 中正确执行锁定 的相关文章

  • 未找到 Boost 库,但编译正常

    我正在尝试在 C 中使用 boost 的文件系统 使用时看起来编译没问题 c c Analyse c o Analyse o g W Wall L usr local lib lboost filesystem lboost system
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • 处理右值时的 insert 与 emplace

    std string myString std unordered set
  • 在 C# 中,如何根据在 gridview 行中单击的按钮引用特定产品记录

    我有一个显示产品网格视图的页面 该表内有一列 其中有一个名为 详细信息 的超链接 我想这样做 以便如果用户单击该特定产品的详细信息单元格 将打开一个新页面 提供有关该产品的更多信息 我不确定如何确定哪个Product记录链接的详细信息以及我
  • 假装 .NET 字符串是值类型

    在 NET 中 字符串是不可变的 并且是引用类型变量 这通常会让新的 NET 开发人员感到惊讶 因为他们的行为可能会将它们误认为是值类型对象 然而 除了使用实践StringBuilder对于长连接 尤其是 在循环中 在实践中是否有任何理由需
  • 如何使用 ASP.NET Core 获取其他用户的声明

    我仍在学习 ASP NET Core 的身份 我正在进行基于声明的令牌授权 大多数示例都是关于 当前 登录用户的 就我而言 我的 RPC 服务正在接收身份数据库中某个用户的用户名和密码 我需要 验证是否存在具有此类凭据的用户 获取该用户的所
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 从 C# 使用 Odbc 调用 Oracle 包函数

    我在 Oracle 包中定义了一个函数 CREATE OR REPLACE PACKAGE BODY TESTUSER TESTPKG as FUNCTION testfunc n IN NUMBER RETURN NUMBER as be
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 模板类中的无效数据类型生成编译时错误?

    我正在使用 C 创建一个字符串类 我希望该类仅接受数据类型 char 和 wchar t 并且我希望编译器在编译时使用 error 捕获任何无效数据类型 我不喜欢使用assert 我怎样才能做到这一点 您可以使用静态断言 促进提供一个 ht
  • 为什么 0.5 mod 0.1 在不同的编程语言中结果不同?

    我有一个关于模数的问题 模运算求一个数除以另一个数的余数 我原本期望 0 5 0 1 0 的结果 但是当我在 PHP 或 net 中运行它时 我得到 0 1 我运行的 php 代码是 var dump fmod 0 5 0 1 在 net中
  • 如何解压 msgpack 文件?

    我正在将 msgpack 编码的数据写入文件 在编写时 我只是使用 C API 的 fbuffer 如 我为示例删除了所有错误处理 FILE fp fopen filename ab msgpack packer pk msgpack pa
  • 从共享网络文件夹运行的 .NET 应用程序的性能损失

    从共享网络文件夹运行 NET 4 0 应用程序是否有任何性能损失 我发现哪个应用程序启动速度较慢 但 在使用时没有注意到任何变慢 但不确定 当通过网络运行可执行文件时 Windows 不会在应用程序启动时通过网络传输整个应用程序 这样做是为
  • WPF DataGrid / ListView 绑定到数组 mvvm

    我们假设你有 N 个整数的数组 表示行数的整数值 在模型中 该整数绑定到视图中的 ComboBox Q1 如何将数组 或数组的各个项目 绑定到 DataGrid 或 ListView 控件 以便 当您更改 ComboBox 值时 只有那么多
  • Visual Studio '17 未在参考管理器中显示程序集

    我遇到的问题是 我似乎无法弄清楚如何添加对某些解决方案的引用 在我从 Visual Studio 17 开始的大多数解决方案中 我在解决方案资源管理器中看到 引用 但例如对于 asp net core web api 我得到 依赖项 每当解
  • 如何隐藏数据列表中的项目

    我想隐藏一个项目datalist根据某种条件起诉ItemBound how Wrap a PlaceHolder控制整个内容ItemTemplate 然后在 ItemDataBound 事件中 您可以执行以下操作 Protected Sub
  • C++:二叉树所有节点值的总和

    我正在准备面试 我被一个二叉树问题困住了 我们如何计算二叉树所有节点中存在的值的总和 优雅的递归解决方案 伪代码 def sum node if node NULL return 0 return node gt value sum nod
  • 在 Win32 控制台应用程序中设置光标位置

    如何在 Win32 控制台应用程序中设置光标位置 最好 我想避免制作句柄并使用 Windows 控制台功能 我花了整个早上沿着那条黑暗的小巷跑 它产生的问题比它解决的问题还要多 我似乎记得当我在大学时使用 stdio 做这件事相对简单 但我
  • MySqlConnectionStringBuilder - 使用证书连接

    我正在尝试连接到 Google Cloud Sql 这是一个 MySql 解决方案 我能够使用 MySql Workbench 进行连接 我如何使用 C 连接MySqlConnectionStringBuilder 我找不到提供这三个证书的

随机推荐

  • 套接字异常:“端点映射器没有更多可用端点”

    我正在使用winsock 和C 来设置服务器应用程序 我遇到的问题是调用listen导致第一次机会异常 我想通常这些可以被忽略 但我发现其他人也有同样的问题 它导致应用程序偶尔挂起 任何帮助将不胜感激 第一个机会例外是 0x 1234567
  • 实现哈希表

    我正在尝试创建一个有效的查找表C 我有一个整数作为键和一个可变长度char 作为值 我看过uthash 但这需要固定长度char 价值 如果我把这个数字设得很大 那么我就使用了太多的内存 struct my struct int key c
  • ASP.Net MVC 的计划控件 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 是否有适用于 ASP Net MVC 的任何商业或其他
  • MAMP Config 帮助,显示 PHP 错误

    我正在 Snow Leopard 上运行最新版本的 MAMP 我的 php ini 文件已配置为显示错误 显示错误 打开 phpinfo 页面显示错误报告状态 为打开状态 我已经多次重新启动我的网络服务器 我用Google搜索过 没有发现类
  • delete[] 如何“知道”操作数数组的大小?

    Foo set new Foo 100 delete set 您没有将数组的边界传递给delete 但这些信息存储在哪里 是否标准化 当您在堆上分配内存时 分配器将跟踪您分配了多少内存 它通常存储在您分配的内存之前的 头 段中 这样 当需要
  • 编写一个有 2 个线程交替打印的程序

    我最近在接受采访时被问到这个问题 编写一个具有两个线程 A 和 B 的程序 其中 A 打印 1 B 打印 2 依此类推 直到达到 50 我们该如何去做呢 分配的本质是演示一个线程如何向另一个线程发出信号 最常见的方法是使用阻塞队列 但这里信
  • 在Python 2.7中模拟按键事件

    我想要做的是在 Windows 上按 Python 脚本级别的任意键盘键 我尝试过 SendKeys 但它仅适用于 python 2 6 我尝试过的其他方法包括 import win32com client win32com client
  • 来自 ADFS 服务器的 URL 重定向

    我在 ASP net Web 应用程序中使用 ADFS 进行身份验证 STS服务器将浏览器重定向到https test contoso com 首先将客户端重定向到 STS 时 STS 不允许任何返回 URL 参数 是否可以将浏览器重定向到
  • 整数除法的行为是什么?

    例如 int result result 125 100 or result 43 100 结果总是分区的底线吗 定义的行为是什么 结果总是分区的底线吗 定义的行为是什么 不完全的 它向 0 舍入 而不是向下舍入 6 5 5 乘法运算符 6
  • Java 的“Parallel.For”?

    我想知道是否有并行 For相当于 Java 的 net 版本吗 如果有人可以提供一个例子吗 谢谢 我想最接近的事情是 ExecutorService exec Executors newFixedThreadPool SOME NUM OF
  • jquery 中的按钮文本切换

    当我单击 pushme 按钮时 它会将其文本变为 不要推我 当再次单击按钮时 我想再次将文本变为 推我 我怎样才能做到这一点
  • 避免应用程序激活并在单击其上的按钮时集中注意力 - Windows API 或 Qt

    情况 无边框 QDialog 成功地保持在其他应用程序之上 问题是当单击此始终位于顶部的应用程序窗口时 会发生以下情况 单击的始终位于顶部的应用程序被激活 单击的始终位于顶部的应用程序窗口会窃取先前活动 聚焦的应用程序的焦点 是否有可能当单
  • YouTube API loadVideoById startSeconds 不起作用

    我为我嵌入的一些 YouTube 视频创建了一个章节选择器 此方法曾经有效 但最近已停止 我不明白发生了什么事 我使用他们推荐的格式 但使用 loadVideoById 来显示每一章 div class wrapper div div di
  • 具有 MVVM 模式的数字文本框

    我见过数字的实现TextBox后面的代码WPF 我们如何做到这一点MVVM图案 在 WPF 中 如果将 TextBox 绑定到 Decimal 或 Int 属性 它将仅接受该 int 或decimal 否则它将显示红色边框 表明它在绑定中没
  • 什么是真与假?它与 True 和 False 有何不同?

    我刚刚了解到有truthy and falsypython 中的值与正常值不同True and False 有人可以深入解释一下什么吗truthy and falsy价值观是 我应该在哪里使用它们 有什么区别truthy and True价
  • 为什么 ${basedir} NLog 配置不起作用?

    为什么我无法在生产服务器中使用 basedir nlog config 如果我使用fileName basedir logs shortdate log nlog 不记录消息信息 但是如果我更改为类似的内容fileName C logs s
  • dockerfile中的EXPOSE和服务YAML中的TARGETPORT与Pod中实际运行的端口有什么关系?

    dockerfile中的EXPOSE和服务YAML中的TARGETPORT与Pod中实际运行的端口有什么关系 在我的 dockerfile 中 expose 8080 在我的部署中 ports containerPort 8080 在我的服
  • fork() 后 libCurl SSL 错误

    我正在开发一个 FUSE 驱动程序 当我将其作为守护进程运行时 没有 f 或 d 标志 通过 libcurl 发出的所有 https 请求都会失败 我能够通过发出 https 请求 分叉并返回父进程 然后从新进程发出第二个请求来重现该错误
  • 查找关联记录存在的位置

    如何仅选择那些具有关联标签记录的员工 换句话说 仅选择具有一个或多个与其关联的标签记录的员工记录 class Employee lt ActiveRecord Base has and belongs to many tags end cl
  • 在 ASP.NET 中正确执行锁定

    我有一个 ASP NET 站点 其搜索功能相当慢 我想通过使用查询作为缓存键将结果添加到缓存一小时来提高性能 using System using System Web using System Web Caching public cla