Di situs web ASP.NET, apakah kelas statis unik untuk setiap permintaan web, atau mereka dipakai setiap kali diperlukan dan GCed setiap kali GC memutuskan untuk membuangnya?
Alasan saya bertanya adalah karena saya telah menulis beberapa kelas statis sebelumnya di C # dan tingkah lakunya berbeda dari yang saya harapkan. Saya akan mengharapkan kelas statis menjadi unik untuk setiap permintaan, tetapi sepertinya bukan itu masalahnya.
Jika mereka tidak unik untuk setiap permintaan, apakah ada cara untuk memungkinkannya?
UPDATE:
Jawaban yang diberikan oleh driis tepat seperti yang saya butuhkan. Saya sudah menggunakan kelas singleton, namun menggunakan contoh statis dan karenanya dibagikan di antara permintaan bahkan jika pengguna berbeda yang dalam hal ini adalah hal yang buruk. Menggunakan HttpContext.Current.Items
memecahkan masalah saya dengan sempurna. Bagi siapa saja yang menemukan pertanyaan ini di masa depan, ini adalah implementasi saya, disederhanakan dan dipersingkat sehingga mudah untuk memahami polanya:
using System.Collections;
using System.Web;
public class GloballyAccessibleClass
{
private GloballyAccessibleClass() { }
public static GloballyAccessibleClass Instance
{
get
{
IDictionary items = HttpContext.Current.Items;
if(!items.Contains("TheInstance"))
{
items["TheInstance"] = new GloballyAccessibleClass();
}
return items["TheInstance"] as GloballyAccessibleClass;
}
}
}
filterContext.Result = new RedirectResult(...)
Anda akan kehilangan item Anda karena HttpContext baru akan dibuat. Lebih detail di sini: stackoverflow.com/questions/16697601/…Jawaban:
Kelas statis dan bidang instance statis Anda dibagikan di antara semua permintaan ke aplikasi, dan memiliki masa pakai yang sama dengan domain aplikasi. Karena itu, Anda harus berhati-hati saat menggunakan instance statis, karena Anda mungkin memiliki masalah sinkronisasi dan sejenisnya. Juga ingat, bahwa instance statis tidak akan GC'ed sebelum kumpulan aplikasi didaur ulang, dan oleh karena itu segala sesuatu yang dirujuk oleh instance statis, tidak akan GC'ed. Ini dapat menyebabkan masalah penggunaan memori.
Jika Anda membutuhkan contoh dengan masa hidup yang sama dengan permintaan, saya akan menyarankan untuk menggunakan
HttpContext.Current.Items
koleksi. Ini dengan desain dimaksudkan untuk menjadi tempat untuk menyimpan barang-barang yang Anda butuhkan sepanjang permintaan. Untuk desain dan keterbacaan yang lebih baik, Anda dapat menggunakan pola Singleton untuk membantu Anda mengelola barang-barang ini. Cukup buat kelas Singleton yang menyimpan instansinya diHttpContext.Current.Items
. (Di perpustakaan umum saya untuk ASP.NET, saya memiliki kelas SingletonRequest generik untuk tujuan ini).sumber
HttpContext.Current.Items
?"static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed"
- Apakah ada sumber untuk ini, karena tidak masuk akal dan bertentangan dengan apa yang saya baca di tempat lain. Ketika AppPool didaur ulang, Domain Aplikasi terkait sepenuhnya dihancurkan dan GC'd. Ketika ini terjadi, setiap instance statis terkait juga akan menjadi GC karena root (AppDomain) hilang. Sebagai bagian dari kumpulan daur ulang, AppDomain baru dibuat dan itu terkait dengan contoh statis diinisialisasi.Anggota statis memiliki ruang lingkup proses pekerja saat ini saja, sehingga tidak ada hubungannya dengan permintaan, karena permintaan yang berbeda mungkin atau mungkin tidak ditangani oleh proses pekerja yang sama.
Ngomong-ngomong, jumlah standar proses pekerja adalah 1, jadi ini sebabnya web penuh dengan orang yang berpikir bahwa anggota statis memiliki cakupan seluruh aplikasi.
sumber
Karena jenisnya terdapat dalam domain aplikasi, saya berharap kelas statis akan ada selama domain aplikasi tidak didaur ulang, atau jika permintaan dilayani oleh domain aplikasi yang berbeda.
Saya dapat memikirkan beberapa cara untuk membuat objek spesifik untuk permintaan tertentu tergantung pada apa yang ingin Anda lakukan, misalnya Anda dapat membuat instance objek di Application.BeginRequest dan kemudian menyimpannya di objek HttpRequest sehingga dapat diakses oleh semua objek di pipa pemrosesan permintaan.
sumber
Nggak. Anggota statis dimiliki oleh proses ASP.NET dan dibagikan oleh semua pengguna aplikasi Web. Anda harus beralih ke teknik manajemen sesi lain seperti variabel sesi.
sumber
Biasanya metode statis, properti, dan kelas umum di
Application
level. Selama aplikasi hidup, mereka dibagikan.Anda dapat menentukan perilaku yang berbeda dengan menggunakan
ThreadStatic
atribut. Dalam hal ini mereka akan spesifik untuk utas saat ini, yang, saya pikir, khusus untuk setiap permintaan.Saya tidak akan menyarankan ini karena tampaknya rumit.
Anda dapat menggunakan
HttpContext.Current.Items
untuk mengatur barang untuk satu permintaan, atauHttpContext.Current.Session
untuk mengatur barang untuk satu pengguna (seluruh permintaan).Secara umum, kecuali Anda harus menggunakan hal-hal seperti
Server.Transfer
, cara terbaik pada dasarnya adalah menciptakan sesuatu sekali dan kemudian mengirimkannya secara eksplisit melalui pemanggilan metode.sumber