Mail İstemcilerinde Çoklu İş Parçacığı Desteği ve Bağlantı Havuzu
Şu gibi posta istemcileri ImapClient, Pop3Client, ve SmtpClient çoklu iş parçacığı ortamında kullanılabilir. Bir istemci bir sunucu ile bir veya daha fazla bağlantı tutabilir. İstemcideki bağlantı setini yönetmek için bir bağlantı havuzu kullanılır. Aynı anda oluşturulup kullanılabilecek bağlantı sayısı CredentialsByHostClient.MaxConnectionsPerServer özelliği. Bu özellik 1 ya da daha büyük bir değere ayarlanabilir. Varsayılan değer 10’dur.
Her bağlantı için çoklu iş parçacığı işlemlerini desteklemek amacıyla bir komut kuyruğu uygulanır. Komutlar, protokolde tanımlı en basit işlemleri gerçekleştirir, örneğin Noop, Authenticate, vb. Bir kullanıcı mevcut bağlantı sayısından daha fazla komut çalıştırmaya başlayabilir, ancak bu komutlar yalnızca istemci bir işlem için bağlantı oluşturabildiğinde yürütülür.
Çok İş Parçacıklı Ortamda Mail İstemcileri Nasıl Davranır
E-posta istemcileri aşağıdaki davranışa sahiptir:
-
When
MaxConnectionsPerServer = 1, istemci bir bağlantı oluşturur ve kimlik doğrulama ve yetkilendirme yapar. Bu bağlantı, istemci serbest bırakılana kadar çalışır durumda tutulur. Farklı iş parçacıklarından gelen tüm işlemler ana bağlantıdaki tek bir komut kuyruğuna yönlendirilir. -
When
MaxConnectionsPerServer > 1, istemci gerekli sayıda bağlantıyı oluşturur ve her bağlantı için kimlik doğrulama ve yetkilendirme yapar. Bir bağlantı ana bağlantı olarak rezerve edilir. Bu bağlantı, istemci serbest bırakılana kadar çalışır durumda tutulur. Diğer tüm bağlantılar ihtiyaç duyulduğunda oluşturulur ve serbest bırakılır. Bu tür bağlantıların en fazla sayısıMaxConnectionsPerServerözelliği. Örneğin, eğerMaxConnectionsPerServer = 2, ardından bir bağlantı ana bağlantı olarak rezerve edilir ve ikinci bir bağlantı diğer iş parçacıklarında gerçekleştirilen işlemler için ek bağlantı olarak kullanılır. Dolayısıyla, eğerMaxConnectionsPerServer = 3, ardından ilk bağlantı ana bağlantı olarak rezerve edilir ve iki başka bağlantı diğer iş parçacıklarında gerçekleştirilen işlemler için ek bağlantı olarak kullanılır. Bir bağlantı talebi yeni bir iş parçacığından geldiğinde ve tüm bağlantılar zaten kullanımdaysa, istemci kullanılabilir bağlantı sayısı azalıncaya kadar bekler. Bu, bağlantıların doğru şekilde serbest bırakılmasının neden bu kadar önemli olduğunu açıklayan çok önemli bir noktadır.
Çok İş Parçacıklı Ortamda Mail İstemcileri Kullanma Örnekleri
Kullanıcı, farklı iş parçacıklarında çeşitli şekillerde işlemler gerçekleştirebilir. İki tipe ayrılırlar.
Asenkron (Begin/End) Metodları Kullanma
Kullanıcı, istemcide tanımlı asenkron (Begin/End) metodları kullanır. Bu durumda posta istemcisi ihtiyaç duyulduğunda yeni iş parçacıkları başlatır. İstemcide bir görev kuyruğu bulunur (bağlantıdaki komut kuyruğuyla karıştırmayın). Bir bağlantı mevcut olduğunda bir görev çalıştırılabilir. Kullanılan bağlantı sayısı limit değerinden düşük olduğunda, istemci yeni bir bağlantı oluşturur, mevcut görev için bir iş parçacığı oluşturur ve bu görevi yürütür. Asenkron işlemlerin bir örneği:
// Create an imapclient with host, user and password
ImapClient client = new ImapClient();
client.Host = "domain.com";
client.Username = "username";
client.Password = "password";
client.SelectFolder("InBox");
ImapMessageInfoCollection messages = client.ListMessages();
IAsyncResult res1 = client.BeginFetchMessage(messages[0].UniqueId);
IAsyncResult res2 = client.BeginFetchMessage(messages[1].UniqueId);
MailMessage msg1 = client.EndFetchMessage(res1);
MailMessage msg2 = client.EndFetchMessage(res2);
Kullanıcı Tarafından Oluşturulan İş Parçacıklarını Kullanma
Kullanıcı, aşağıdaki gibi nesnelerle iş parçacıkları oluşturabilir Thread, ThreadPool, Task, veya bu amaçla tasarlanmış diğer nesneler. Kullanıcı üçüncü taraf kodda oluşturulan iş parçacıklarını da kullanabilir. Bu durumda istemcinin iki davranış modeli vardır.
a. Kullanıcı, iş parçacığı için ek bağlantılar oluşturma konusunu halletmemişse, bu iş parçacığına ait tüm işlemler ana bağlantının komut kuyruğuna gönderilir. Aşağıda yeni bir bağlantı oluşturmadan ek bir iş parçacığındaki işlemlere bir örnek verilmiştir — tüm işlemler ana bağlantı üzerinden yapılır:
List<MailMessage> List = new List<MailMessage>();
ThreadPool.QueueUserWorkItem(delegate(object o)
{
client.SelectFolder("folderName");
ImapMessageInfoCollection messageInfoCol = client.ListMessages();
foreach (ImapMessageInfo messageInfo in messageInfoCol)
{
List.Add(client.FetchMessage(messageInfo.UniqueId));
}
});
b. Kullanıcı ek bir iş parçacığı için yeni bir bağlantı oluşturma metodunu çalıştırdığında, bu iş parçacığı yeni bağlantı izni veren kota değeri değişene kadar engellenir. Daha sonra yeni bir bağlantı oluşturulur. Bu bağlantı, bu iş parçacığındaki tüm işlemler için varsayılan bağlantı olarak ayarlanır. İşlem tamamlandığında bağlantı serbest bırakılmalıdır. Yeni bağlantılar oluşturmak için CredentialsByHostClient.CreateConnection metodu. Bu metod, IDisposable arayüzü. Bağlantıyı serbest bırakmak için, Dispose metodu çağrılmalıdır. Bir bağlantının oluşturulması ve serbest bırakılması, posta işlemlerinin yürütüldüğü iş parçacığı içinde gerçekleştirilmelidir. Posta istemcisi oluşturulan iş parçacığında yeni bir bağlantı oluşturmaya çalışmak bir hataya yol açar, çünkü bu iş parçacığı o anda yeni bir bağlantı oluşturmak için kullanılamaz. Ayrıca yeni bir bağlantı MaxConnectionsPerServer = 1. Ek bir iş parçacığında yeni bir bağlantı oluşturma kod örneği:
List<MailMessage> List1 = new List<MailMessage>();
ThreadPool.QueueUserWorkItem(delegate(object o)
{
using (IDisposable connection = client.CreateConnection())
{
client.SelectFolder("FolderName");
ImapMessageInfoCollection messageInfoCol = client.ListMessages();
foreach (ImapMessageInfo messageInfo in messageInfoCol)
List1.Add(client.FetchMessage(messageInfo.UniqueId));
}
});
Bağlantı Havuzu
Aspose.Email 19.3 ile başlayan sürümde bağlantı havuzu yeniden düzenlendi. EmailClient class tanıtıldı, bu sonunda CredentialsByHostClient sınıf. EmailClient sınıf bir … sağlar ConnectionAsgmtMode çok iş parçacıklı bir ortamda bağlantı tahsis modunu tanımlayan özellik. EmailClient.ConnectionAsgmtMode … ile ayarlanır ConnectionAsgmtType enum.
Bağlantı Türleri
Üç bağlantı türü vardır:
- Ana bağlantı. Bu, posta istemcisiyle birlikte oluşturulan ve serbest bırakılan bağlantıdır. Manuel olarak oluşturulamaz ya da serbest bırakılamaz.
- Varsayılan bağlantı. Kullanıcı, iş parçacıkları için varsayılan bağlantıları CreateConnection metodu ile oluşturulabilir. Bir varsayılan bağlantı varsa, bir iş parçacığında yürütülen e-posta istemcisi metodlarının tümü bu bağlantıyı örtük olarak kullanır. Her iş parçacığı başına yalnızca bir varsayılan bağlantı bulunabilir. Bu, bağlantı tahsis moduna bağlı olarak manuel ya da otomatik olarak oluşturulabilir.
EmailClient.ConnectionAsgmtModeözelliği. Bu bağlantılar manuel olarakEmailClient.CreateConnection(createAsDefaultConnection = true)metodu ile manuel olarak oluşturulabilir. Bir varsayılan bağlantı kullanılmazsa (bağlantı tahsis moduna bağlı olarak), ana bağlantı yerine örtük olarak kullanılır. - Bağımsız bağlantılar. Bunlar iş parçacıklarına bağlı olmayan bağlantılardır. Manuel olarak oluşturulabilir ve yöntem parametresi olarak açıkça kullanılmalıdır. Bu bağlantılar
EmailClient.CreateConnection()metodu ya daEmailClient.CreateConnection(createAsDefaultConnection = false)metod.
Bağlantı Tahsis Türleri
Ayarlamak için EmailClient.ConnectionAsgmtMode özelliği, ConnectionAsgmtType enumeration kullanılarak oluşturulur. Sağladığı tahsis türleri aşağıda listelenmiştir.
-
ConnectionAsgmtType.UseMainOrDefault Bu mod e-posta istemcilerinde varsayılan olarak kullanılır. Varsayılan bağlantı oluşturulmamışsa veya bir bağlantı açıkça bir yöntem parametresi olarak geçilmemişse, e-posta istemcisi birden çok iş parçacığından gelen tüm işlemler için ana bağlantıyı kullanır. Ana bağlantı e-posta istemcisiyle aynı anda oluşturulur. Kullanıcı, iş parçacıkları için varsayılan bağlantıları
CreateConnectionyöntemiyle düzgün çalıştığını unutmayın. Bir iş parçacığı için varsayılan bağlantı oluşturulmuşsa, bu bağlantı o iş parçacığında çağrılan e-posta istemcisi metodlarının tümü için örtük olarak kullanılır. Bir iş parçacığı için varsayılan bağlantı oluşturulmamışsa, ana bağlantı o iş parçacığında çağrılan tüm metodlar için kullanılır. Kullanıcı ayrıca iş parçacıklarına bağlı olmayan (varsayılan olmayan) bağlantılarıCreateConnectionyöntemi. Diğer bağlantıları (ana ve varsayılan olmayan) kullanmak için kullanıcı bağlantıyı açıkça bir yöntem parametresi olarak geçmelidir. Kullanıcı ayrıca istediği kadar bağlantı oluşturabilir. Her iş parçacığı başına yalnızca bir varsayılan bağlantı bulunabilir. Lütfen varsayılan bağlantıların, kullanıcıThreadçoklu görev programlama nesneleri. Kullanıcı bir bağlantı havuzu kullanıyorsa veyaTaskçoklu görev nesneleri, bu mod hatalı davranışa yol açabilir. Bu sorunu önlemek için kullanıcı kod yürütmesinin sonunda varsayılan bağlantıyı (kullanılıyorsa) manuel olarak serbest bırakmalıdır. -
ConnectionAsgmtType.UseMain E-posta istemcisi, birden çok iş parçacığından gelen tüm işlemler için ana bağlantıyı kullanır. Ana bağlantı e-posta istemcisiyle aynı anda oluşturulur. Kullanıcı varsayılan bağlantı oluşturamaz, ancak
CreateConnectionyöntemiyle iş parçacıkları için varsayılan bağlantılar oluşturamaz. Diğer bağlantıları kullanmak için kullanıcı bunları açıkça bir yöntem parametresi olarak geçmelidir. -
ConnectionAsgmtType.UseDefault E-posta istemcisi, birden çok iş parçacığından gelen tüm işlemler için yalnızca varsayılan bağlantıları örtük şekilde kullanır. Bu modda ana bağlantı kullanılmaz. Bir iş parçacığı için (e-posta istemcisi yönteminin ilk çağrısında) bir varsayılan bağlantı oluşturulmamışsa, e-posta istemcisi ilk işlem yürütülmeden önce iş parçacığı için bir varsayılan bağlantı örtük olarak oluşturur. Kullanıcı,
CreateConnectionyöntemiyle otomatik olarak oluşturulduğu için düzgün çalıştığını unutmayın. Kullanıcı ayrıca bağlantıları,CreateConnectionyöntemi. Diğer bağlantıları kullanmak için kullanıcı bunları açıkça bir yöntem parametresi olarak geçmelidir. Kullanıcı ayrıca istediği kadar bağlantı oluşturabilir. Her iş parçacığı başına yalnızca bir varsayılan bağlantı kullanılabilir. Lütfen varsayılan bağlantıların, kullanıcıThreadçoklu görev programlama nesneleri. Kullanıcı bir bağlantı havuzu kullanıyorsa veyaTaskçoklu görev için nesneler, bu mod hatalı davranışa yol açabilir. Bu sorunu önlemek için kullanıcı kod yürütmesinin sonunda varsayılan bağlantıyı manuel olarak serbest bırakmalıdır.
Öneriler
Kullanıcı tüm komutları ana bağlantıya gönderirse, farklı iş parçacıklarından gelen komutların karıştığı bir durum ortaya çıkabilir. Kullanıcı, hangi komutların sırasına bağlı olduğunu anlamalı ve bu tür komutları senkronize etmek için önlemler almalıdır. Ayrıca komutların farklı oturumlarda (IMAP/POP3) çalıştırılma olasılığını da göz önünde bulundurmak gerekir. En çok zaman alan işlemler şunlardır FetchMessage, AppendMessage, ve Send. Bu işlemlerin yeni bir iş parçacığı ve yeni bir bağlantı ile yapılması mantıklı olabilir. Hızlı işlemler gibi Delete ana bağlantı ile gerçekleştirilmesi mantıklı olabilir. Yeni bir bağlantının başlatılmasının oldukça zaman alıcı bir işlem olduğunu lütfen unutmayın.