You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET SqlDataSource缓存设置:整点每10分钟精准过期

Great question! Your two approaches both address the core problem perfectly—making sure your GridView cache expires exactly when the round switches, not just 10 minutes after the first request. Let’s break down each method with practical implementation details so you can pick what works best for your game.

Approach 1: Dynamically Calculate Cache Duration Per Data Source

This method is ideal if you want each SqlDataSource to independently manage its cache without relying on global state. The idea is to calculate how many seconds remain until the next 10-minute round switch, then set that as the CacheDuration.

Implementation Steps:

  1. When binding your GridView (on Page_Load or the SqlDataSource’s Selecting event), check if the cache for that data source already exists.
  2. If not, compute the time until the next round switch and set the cache duration accordingly.

Here’s a code example in C#:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        SetupDynamicCache(PlayerStatsGridView.DataSource as SqlDataSource);
    }
}

private void SetupDynamicCache(SqlDataSource dataSource)
{
    // Use a unique cache key to track if this data source's cache is active
    string cacheTrackKey = $"SqlCache_{dataSource.ID}_Active";
    
    if (HttpContext.Current.Cache[cacheTrackKey] == null)
    {
        DateTime now = DateTime.Now;
        // Calculate minutes until next 10-minute interval (e.g., 10:05 → 5 mins to 10:10; 10:10 → 10 mins to 10:20)
        int minutesToNextRound = (10 - (now.Minute % 10)) % 10;
        if (minutesToNextRound == 0) minutesToNextRound = 10;
        
        int cacheDurationSeconds = minutesToNextRound * 60;
        
        // Enable caching and set the calculated duration
        dataSource.EnableCaching = true;
        dataSource.CacheDuration = cacheDurationSeconds;
        
        // Track the cache's lifespan so we don't recalculate on every postback
        HttpContext.Current.Cache.Insert(
            cacheTrackKey, 
            true, 
            null, 
            DateTime.Now.AddSeconds(cacheDurationSeconds), 
            Cache.NoSlidingExpiration
        );
    }
}

Pros & Cons:

  • ✅ No dependency on global round state—each data source handles its own cache.
  • ✅ Works seamlessly for scattered pages or data sources that don’t need coordinated cache invalidation.
  • ⚠️ If a user visits right before a round switch, the cache might only last a few seconds, but this is intentional (since the data is about to update anyway).

Approach 2: Batch Invalidate Cache On Round Switch

If your game already tracks the current round via an application-level variable, this method is cleaner. You’ll clear all relevant SqlDataSource caches when the round switches, then set a fixed 10-minute cache duration for the new round.

Implementation Steps:

  1. Update your round-switch logic to set an application-level variable (e.g., CurrentRound) when a new round starts.
  2. On page load, check if the current round matches the round stored with the data source’s cache. If not, invalidate the cache and refresh it.

Step 1: Update Round State On Switch

// Call this method after your round-switch logic completes
void UpdateCurrentRound(int newRoundNumber)
{
    // Store the round in Application state or a persistent cache
    Application.Lock();
    Application["CurrentRound"] = newRoundNumber;
    Application.UnLock();
    
    // Alternatively, use Cache for better scalability
    HttpContext.Current.Cache.Insert(
        "CurrentRound", 
        newRoundNumber, 
        null, 
        Cache.NoAbsoluteExpiration, 
        Cache.NoSlidingExpiration
    );
}

Step 2: Check And Invalidate Stale Cache

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ValidateRoundCache(PlayerStatsGridView.DataSource as SqlDataSource);
    }
}

private void ValidateRoundCache(SqlDataSource dataSource)
{
    int currentRound = (int)Application["CurrentRound"];
    string cacheRoundKey = $"SqlCache_{dataSource.ID}_Round";
    
    // Get the round number associated with the current cache
    int? cachedRound = HttpContext.Current.Cache[cacheRoundKey] as int?;
    
    if (cachedRound != currentRound)
    {
        // Invalidate the existing cache for this data source
        dataSource.InvalidateCache();
        
        // Set cache to last 10 minutes until the next round
        dataSource.EnableCaching = true;
        dataSource.CacheDuration = 600;
        
        // Update the cached round number to match the current round
        HttpContext.Current.Cache.Insert(
            cacheRoundKey, 
            currentRound, 
            null, 
            DateTime.Now.AddMinutes(10), 
            Cache.NoSlidingExpiration
        );
    }
}

Pros & Cons:

  • ✅ Simplified logic—cache lasts a full 10 minutes, and you only invalidate when the round changes.
  • ✅ Easy to coordinate cache invalidation across all pages/data sources.
  • ⚠️ Requires a reliable global round-tracking system—you need to ensure CurrentRound is updated correctly every time a round switches.

Final Recommendations

  • Go with Approach 2 if your game already has a centralized round-management system. It’s more efficient and easier to maintain.
  • Use Approach 1 if you have scattered pages/data sources or don’t want to rely on global state.

A quick bonus tip: For either method, use SqlDataSource.CacheKeyDependency to group related cache items. This lets you invalidate all caches for a specific game module with a single key, instead of handling each data source individually.

内容的提问来源于stack exchange,提问作者Ozzie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:45:40