mengapa objek statis saya dibuat beberapa kali dalam kode asp.net saya?

Saya pikir objek statis dibagikan ke beberapa utas. Namun, saya mendapat masalah CPU yang tinggi di salah satu situs saya, jadi saya mengambil dump windbg dan sangat terkejut, saya melihat ini:

masukkan deskripsi gambar di sini

Kita dapat melihat bahwa ada 10 instance dari kelas yang disebut ConnectionMultiplexer. Tapi kode saya membuat ConnectionMultiplexer sebagai objek statis. Artinya, hanya satu instance yang dibuat untuk semua thread. Jadi kenapa windbg menampilkan banyak contoh?

Ini adalah kode saya untuk membuat koneksi redis

public static class CacheConnection
    {
        private static StackExchangeRedisCacheClient _newconnectionDb;

        public static StackExchangeRedisCacheClient NewConnectionDb
            => _newconnectionDb ?? (_newconnectionDb = NewRedisConnection());

        private static IDatabase _connectionDb;

        public static IDatabase ConnectionDb => _connectionDb ?? (_connectionDb = RedisConnection());

        private static StackExchangeRedisCacheClient NewRedisConnection()
        {
            var serializer = new NewtonsoftSerializer();
            return new StackExchangeRedisCacheClient(Connection, serializer);
        }

        private static IDatabase RedisConnection()
        {
            var cacheDatabase = Connection.GetDatabase();
            return cacheDatabase;
        }

        public static ConnectionMultiplexer Connection => LazyConnection.Value;

        private static readonly Lazy<ConnectionMultiplexer> LazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(
            System.Configuration.ConfigurationManager.AppSettings["CacheConnectionString"]), LazyThreadSafetyMode.PublicationOnly);
    }

person daxu    schedule 28.09.2017    source sumber
comment
Mengenai kalimat pertama Anda: Objek apa pun ada di heap dan heap tersedia untuk thread mana pun. Jadi fakta bahwa itu statis tidak menjadi masalah.   -  person Thomas Weller    schedule 28.09.2017


Jawaban (1)


ConnectionMultiplexer sebenarnya adalah properti readonly (dapatkan) menggunakan sintaks pendek C# 7 baru => yang mengembalikan LazyConnection.Value setiap kali Anda mengaksesnya.

Kemudian Anda menggunakan LazyThreadSafetyMode.PublicationOnly yang didefinisikan seperti ini di MSDN (https://msdn.microsoft.com/en-us/library/system.threading.lazythreadsafetymode(v=vs.110).aspx)

Ketika beberapa thread mencoba menginisialisasi instance Lazy secara bersamaan, semua thread diizinkan menjalankan metode inisialisasi (atau konstruktor default, jika tidak ada metode inisialisasi). Thread pertama yang menyelesaikan inisialisasi menetapkan nilai instance Lazy. Nilai tersebut dikembalikan ke thread lain yang secara bersamaan menjalankan metode inisialisasi, kecuali metode inisialisasi memberikan pengecualian pada thread tersebut. Setiap contoh T yang dibuat oleh thread yang bersaing akan dibuang. Jika metode inisialisasi memunculkan pengecualian pada thread mana pun, pengecualian tersebut disebarkan keluar dari properti Lazy.Value pada thread tersebut. Pengecualian tidak di-cache. Nilai properti IsValueCreated tetap salah, dan panggilan selanjutnya ke properti Value, baik oleh thread tempat pengecualian dilemparkan atau oleh thread lain, menyebabkan metode inisialisasi dijalankan kembali. Jika metode inisialisasi secara rekursif mengakses properti Value dari instance Lazy, tidak ada pengecualian yang akan ditampilkan.

Ini berarti bahwa jika beberapa thread mencoba mengaksesnya dalam waktu yang sama, masing-masing thread akan membuat instance-nya sendiri meskipun pada akhirnya Anda akan menggunakan thread pertama yang dibuat terlepas dari threadnya (tetapi instance-nya masih ada).

Yang sebenarnya Anda perlukan adalah LazyThreadSafetyMode.ExecutionAndPublication tetapi ini mungkin menimbulkan kebuntuan.

Jika Anda tidak membutuhkan ini untuk menjadi Malas, Anda dapat menggunakan salah satu implementasi pola tunggal yang disarankan oleh Jon Skeet dalam bukunya C# In Depth

Anda dapat menemukannya di sini http://csharpin depth.com/Articles/General/Singleton.aspx

person Mihail Shishkov    schedule 28.09.2017