using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyWebApplication.Cache
{
	public partial class DataCache_Markers : System.Web.UI.Page
	{
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			ClearMarkerGroup.Click += new EventHandler(ClearMarkerGroup_Click);

			BindValues();
		}

		private void BindValues()
		{
			DateTimeLb.Text = DateTime.Now.ToString();
			DataLb.Text = GetData();
			MarkerGroupData1Lb.Text = GetMarkerData1();
			MarkerGroupData2Lb.Text = GetMarkerData2();
		}

		void ClearMarkerGroup_Click(object sender, EventArgs e)
		{
			HttpRuntime.Cache.Remove(CacheMarkerKey);
			BindValues();
		}

		private static string CacheMarkerKey = "MyCacheMarkerGroup1";
		private void EnsureCacheMarker(string cacheMarkerKey)
		{
			if (HttpRuntime.Cache[cacheMarkerKey] == null)
			{
				// zjendodušeno bez lockingu a double-checkingu
				HttpRuntime.Cache[cacheMarkerKey] = new object();
			}
		}

		private string GetMarkerData1()
		{
			const string cacheKey = "MyMarkedData1";

			string result = (string)HttpRuntime.Cache[cacheKey];
			if (result == null)
			{
				// zjednodušeno bez lockingu a double-checkingu
				result = FetchData1FromDB();

				EnsureCacheMarker(CacheMarkerKey);

				HttpRuntime.Cache.Add(
					key: cacheKey,
					value: result,
					dependencies: new CacheDependency(filenames: null, cachekeys: new string[] { CacheMarkerKey }),
					absoluteExpiration: DateTime.Now.AddSeconds(60),
					slidingExpiration: System.Web.Caching.Cache.NoSlidingExpiration,
					priority: System.Web.Caching.CacheItemPriority.Normal,
					onRemoveCallback: null);
			}
			return result;
		}

		private string FetchData1FromDB()
		{
			return DateTime.Now.ToString();
		}



		private string GetMarkerData2()
		{
			const string cacheKey = "MyMarkedData2";

			string result = (string)HttpRuntime.Cache[cacheKey];
			if (result == null)
			{
				// zjendodušeno bez lockingu a double-checkingu
				result = FetchData2FromDB();

				EnsureCacheMarker(CacheMarkerKey);

				HttpRuntime.Cache.Add(
					key: cacheKey,
					value: result,
					dependencies: new CacheDependency(filenames: null, cachekeys: new string[] { CacheMarkerKey }),
					absoluteExpiration: DateTime.Now.AddSeconds(60),
					slidingExpiration: System.Web.Caching.Cache.NoSlidingExpiration,
					priority: System.Web.Caching.CacheItemPriority.Normal,
					onRemoveCallback: null);
			}
			return result;
		}

		private string FetchData2FromDB()
		{
			return DateTime.Now.ToString();
		}







		private static object myDataLock = new object();
		private string GetData()
		{
			const string cacheKey = "MyData";

			string result = (string)HttpRuntime.Cache[cacheKey];
			if (result == null)
			{
				lock (myDataLock) // lock + double-check
				{
					result = (string)HttpRuntime.Cache[cacheKey];
					if (result == null)
					{
						result = FetchDataFromDB();

						HttpRuntime.Cache.Add(
							key: cacheKey,
							value: result,
							dependencies: null,
							absoluteExpiration: DateTime.Now.AddSeconds(60),
							slidingExpiration: System.Web.Caching.Cache.NoSlidingExpiration,
							priority: System.Web.Caching.CacheItemPriority.Normal,
							onRemoveCallback: null);
					}
				}
			}
			return result;
		}

		private string FetchDataFromDB()
		{
			return DateTime.Now.ToString();
		}
	}
}