ASP.NET載入共用大型物件的另一種方式

在ASP.NET中,如果要讓一個大型物件被所有的request共用,在網站啟動時會先建立,之中會加入lock語法,避免多次重覆建立物件,如果又加上快取機制,那程式碼又會因為加上if-else而變得更亂。好在C#有Lazy類別可以使用,它是Thread-Safe的,以下是示範:
public class LargeObjectManager
{
public LargeObjectManager() { }
private static MemoryCache _cache = MemoryCache.Default;
public DemoClass GetDemoClass()
{
var demo1 = new Lazy<DemoClass>(() =>
{
// 證明這裡的程式碼只會執行一次,因為 Lazy<T> 會確保只有第一次讀取 Value 時才會執行這段程式碼
Console.WriteLine("Creating DemoClass instance...");
return new DemoClass { Name = "Demo1", Description = "This is demo 1", Age = 30 };
});
CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(10) };
var item = _cache.AddOrGetExisting("Demo1", demo1, policy) as Lazy<DemoClass>;
var existingDemo = item ?? demo1;
var result = existingDemo.Value;
return result;
}
}
然後用Console程式來示範,這邊同時平行執行5個執行緒,看大型物件是不是有重覆產生:
Stack<string> stack = new Stack<string>();
stack.Push("First");
stack.Push("Second");
stack.Push("Third");
stack.Push("Fourth");
stack.Push("Fifth");
Parallel.For(0, 5, i =>
{
string item = stack.Pop();
Console.WriteLine($"Popped item: {item}");
LargeObjectManager largeObjectManager = new LargeObjectManager();
var result = largeObjectManager.GetDemoClass();
Console.WriteLine(JsonSerializer.Serialize(result));
});
執行結果:
