Dukungan multi-threading pada klien email

Klien email seperti ImapClient dan Pop3Client memungkinkan pengguna menggunakannya dalam lingkungan multithreading. Klien email memungkinkan memiliki satu atau lebih koneksi dengan server. Untuk mengelola sekumpulan koneksi di dalam klien digunakan connection pool. Jumlah koneksi yang dapat dibuat dan digunakan secara bersamaan dibatasi oleh properti CredentialsByHostClient.MaxConnectionsPerServer. Properti ini dapat diatur menjadi 1 atau nilai lebih besar. Secara default properti ini bernilai 10. Antrian perintah telah diimplementasikan untuk koneksi guna mendukung operasi multithreading. Perintah mengimplementasikan operasi sederhana yang didefinisikan dalam protokol, seperti Noop, Authenticate, dan sebagainya. Pengguna dapat memulai eksekusi jumlah perintah lebih banyak daripada jumlah koneksi yang tersedia. Tetapi perintah akan dijalankan hanya ketika klien dapat membuat koneksi untuk operasi tersebut.

Metode menggunakan klien email dalam lingkungan multithreading

Klien email memiliki perilaku berikut:

1. Jika MaxConnectionsPerServer = 1, klien membuat 1 koneksi, melakukan autentikasi dan otorisasi. Koneksi ini dipertahankan dalam keadaan kerja sampai klien dibuang. Semua operasi dari thread yang berbeda diarahkan ke satu antrian perintah yang ditempatkan pada koneksi utama.

2. Jika MaxConnectionsPerServer > 1, klien membuat jumlah koneksi yang diperlukan, melakukan autentikasi dan otorisasi untuk setiap koneksi. Satu koneksi dicadangkan sebagai koneksi utama. Koneksi ini dipertahankan dalam keadaan kerja sampai klien dibuang. Semua koneksi lain dibuat dan dibuang sesuai permintaan. Jumlah maksimal koneksi tersebut ditentukan oleh properti MaxConnectionsPerServer, misalnya jika MaxConnectionsPerServer = 2 maka satu koneksi dicadangkan sebagai koneksi utama, dan koneksi kedua digunakan sebagai tambahan untuk operasi yang dijalankan di thread lain. Demikian pula, jika MaxConnectionsPerServer = 3 maka koneksi pertama dicadangkan sebagai koneksi utama, dan dua koneksi lainnya digunakan sebagai tambahan untuk operasi yang dijalankan di thread lain. Jika ada permintaan koneksi berikutnya dari thread baru, dan semua koneksi sudah digunakan, klien akan menunggu hingga jumlah koneksi yang digunakan berkurang. Ini adalah momen penting yang menjelaskan mengapa pembuangan koneksi yang tepat sangat penting.

Contoh

Pengguna dapat mengeksekusi operasi di thread yang berbeda dengan beberapa cara. Mereka dapat dibagi menjadi dua tipe:

1. Pengguna menggunakan metode asynchronous (Begin/End) yang didefinisikan dalam klien. Dalam hal ini klien email meluncurkan thread baru bila diperlukan. Di dalam klien diterapkan antrian tugas (harap tidak bingung dengan antrian perintah pada koneksi). Tugas dapat dijalankan jika koneksi tersedia. Setelah jumlah koneksi yang digunakan menjadi kurang dari nilai batas, klien membuat koneksi baru, membuat thread untuk tugas saat ini, dan mengeksekusi tugas tersebut. Contoh penggunaan operasi asynchronous:

2. Pengguna dapat membuat thread menggunakan objek seperti Thread, ThreadPool, Task, atau objek lain yang dimaksud untuk tujuan ini. Pengguna juga dapat menggunakan thread yang dibuat dalam kode pihak ketiga. Selama ini klien memiliki dua model perilaku

a. Jika pengguna tidak membuat koneksi tambahan untuk operasi di thread, semua operasi untuk thread ini akan dikirim ke antrian perintah pada koneksi utama. Contoh operasi pada thread tambahan tanpa membuat koneksi baru, semua transaksi dilakukan melalui koneksi utama:

b. Ketika pengguna menjalankan metode untuk membuat koneksi baru untuk thread tambahan, thread ini akan diblokir hingga nilai kuota untuk koneksi baru diubah sehingga mengizinkan koneksi baru. Setelah itu koneksi baru dibuat. Koneksi ini ditetapkan sebagai koneksi default untuk semua operasi di thread ini. Setelah semua operasi di thread ini selesai, koneksi harus dibuang. Untuk membuat koneksi baru gunakan metode CredentialsByHostClient.CreateConnection. Metode ini mengembalikan objek yang mengimplementasikan antarmuka IDisposable. Untuk melepaskan koneksi, metode Dispose harus dipanggil. Pembuatan dan pembongkaran koneksi harus dilakukan di dalam thread tempat operasi email dijalankan. Upaya membuat koneksi baru di thread tempat klien email dibuat akan menghasilkan error, karena thread tersebut pada saat ini tidak dapat digunakan untuk membuat koneksi baru. Selain itu, pembuatan koneksi baru tidak memungkinkan ketika MaxConnectionsPerServer = 1. Contoh kode untuk membuat koneksi baru pada thread tambahan:

Rekomendasi

Perlu dicatat bahwa jika pengguna mengirim semua perintah ke koneksi utama, dapat muncul situasi di mana perintah dari thread yang berbeda tercampur. Pengguna harus memahami perintah mana yang bergantung pada urutannya, dan mengambil langkah-langkah sinkronisasi untuk perintah tersebut. Juga perlu mempertimbangkan kemungkinan mengeksekusi perintah dalam sesi yang berbeda (IMAP/POP3). Operasi yang paling memakan waktu, seperti FetchMessage, AppendMessage, dan Send, mungkin lebih baik dijalankan dengan thread baru dan koneksi baru. Namun operasi cepat seperti Delete lebih tepat dijalankan dengan koneksi utama. Harap dicatat bahwa inisialisasi koneksi baru merupakan operasi yang cukup memakan waktu.