精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

.NET開發(fā)郵件發(fā)送功能的全面教程(含郵件組件源碼)

開發(fā) 后端
今天,給大家分享的是如何在.NET平臺中開發(fā)“郵件發(fā)送”功能。在網(wǎng)上搜的到的各種資料一般都介紹的比較簡單,那今天我想比較細的整理介紹下。

今天,給大家分享的是如何在.NET平臺中開發(fā)“郵件發(fā)送”功能。在網(wǎng)上搜的到的各種資料一般都介紹的比較簡單,那今天我想比較細的整理介紹下:

1) 郵件基礎理論知識

2) 郵件發(fā)送相關(guān).NET類庫

3) 介紹我開發(fā)的一個發(fā)送郵件的小組件(MailHelper)

4) MailHelper組件的一個示例以及幾種方式發(fā)郵件的優(yōu)劣測試

示例及組件源碼:

.NET開發(fā)郵件發(fā)送功能的全面教程(含郵件組件源碼).rar

郵件基礎理論知識

什么業(yè)務需要郵件功能?

1. 服務提供方:需提供郵件收發(fā)客戶端或Web服務。(eg:Outlook、QQ郵箱)。當然這些服務都是知名商提供。若是一般的小網(wǎng)站提供的郵件收發(fā)服務,不知道節(jié)操如何,誰敢用呢?就算你用了,別的知名商SMTP服務器也不認可從這小網(wǎng)站發(fā)出的郵件,出現(xiàn)SMTP服務器拒收來源郵件(視為惡意郵件或垃圾郵件)。

2. 安全性、機密性:比如某安全部門需要提供自己發(fā)郵件的SMTP服務器和收郵件POP3服務器以及相應的操作軟件

3. 電子商務、論壇等會員機制社區(qū):主家需要向會員發(fā)送通知信息,比如:密碼重置、降價通知、留言通知、回復通知、訂閱通知、會員間交流等等。主家保證郵箱有效性的辦法常常是通過會員注冊、更換郵箱時發(fā)送“激活郵件”。

4. 郵件營銷:在大數(shù)據(jù)時代的現(xiàn)在,企業(yè)可以根據(jù)所掌握的數(shù)據(jù)預測客戶的需求,來提供主動推送營銷消息的功能;當然也有沒有預測能力的小商家通過郵件群發(fā)器進行撒網(wǎng)式郵件營銷。

5. 等等

什么是電子郵件協(xié)議?

當前常用的電子郵件協(xié)議有SMTP、POP3、IMAP4,它們都隸屬于TCP/IP協(xié)議簇。

1. SMTP

Simple Mail Transfer Protocol(即簡單郵件傳輸協(xié)議),它是一組用于從源地址到目的地址傳送郵件的規(guī)則,簡單的說就是:From-->To的傳送規(guī)則。由SMTP來控制信件中轉(zhuǎn)的方式。SMTP屬于TCP/IP家族中的一員,它幫助每一臺計算機在發(fā)送或中轉(zhuǎn)信件時找到下一個目的地。通過SMTP協(xié)議所指定的服務器,就可以把E-Mail寄到收信人的服務器上。SMTP服務器則是遵循SMTP協(xié)議的郵件發(fā)送服務器,用來中轉(zhuǎn)你發(fā)出的電子郵件。

SMTP目前已是事實上的E-Mail傳輸?shù)臉藴省?/p>

2. POP3

Post Office Protocol 3(即郵局協(xié)議的第3個版本),負責從郵件服務器中檢索電子郵件。它要求郵件服務器完成下面幾種任務之一:從郵件服務器中檢索郵件并從服務器中刪除這個郵件;從郵件服務器中檢索郵件但不刪除它;不檢索郵件,只是詢問是否有新郵件到達。

POP3是因特網(wǎng)電子郵件的第一個離線協(xié)議標準。

3. IMAP4

Internet Message Access Protocol 4(即交互式數(shù)據(jù)消息訪問協(xié)議第四個版本),提供脫機和聯(lián)機訪問功能。是一種優(yōu)于POP的新協(xié)議,是美國斯坦福大學在1986年開始研發(fā)的多重郵箱電子郵件系統(tǒng)。和POP一樣,IMAP也能下載郵件、從服務器中刪除郵件或詢問是否有新郵件,但IMAP克服了POP的一些缺點。例如,請求郵件服務器只下載所選中的郵件而不是全部郵件??蛻魴C可先閱讀郵件信息的標題和發(fā)送者的名字再決定是否下載這個郵件。通過用戶的客戶機電子郵件程序,IMAP可讓用戶在服務器上創(chuàng)建并管理郵件文件夾或郵箱、刪除郵件、查詢某封信的一部分或全部內(nèi)容,完成所有這些工作時都不需要把郵件從服務器下載到用戶的個人計算機上。

默認情況下,當 IMAP4 電子郵件應用程序?qū)㈦娮余]件下載到客戶端計算機,下載郵件的副本會保留在電子郵件服務器上。正是由于用戶的電子郵件副本保留在電子郵件服務器上,用戶可以從多臺計算機上訪問相同的電子郵件。也可以實現(xiàn)電子郵件服務器上的多個文件夾與客戶端計算機上的多個文件夾同步。

SMTP/POP3工作方式如圖:

image

TCP的3次握手和4次揮手?

詳細可見TCP3次握手/4次握手》

在 TCP 數(shù)據(jù)段報頭中,有六個包含控制信息的 1 bit字段,用于管理 TCP 進程。這些字段分別是:

URG —緊急指針

ACK —確認字段

PSH —推送功能

RST —重置連接

SYN —同步序列號

FIN —發(fā)送方已傳輸完所有數(shù)據(jù)

這些字段用作標志,由于它們都只有 1 bit大小,所以它們都只有兩個值:1 或者 0。當值設為 1 時,表示數(shù)據(jù)段中包含控制信息。

1. 三次握手,建立連接

在TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務,采用三次握手建立一個連接。

1) 建立連接時,客戶端A發(fā)送SYN包(SYN=j)到服務器B,并進入SYN_SEND狀態(tài),等待服務器B確認。

2) 服務器B收到SYN包,必須確認客戶A的SYN(ACK=j+1),同時自己也發(fā)送一個SYN包(SYN=k),即SYN+ACK包,此時服務器B進入SYN_RECV狀態(tài)。

3) 客戶端A收到服務器B的SYN+ACK包,向服務器B發(fā)送確認包ACK(ACK=k+1),此包發(fā)送完畢,客戶端A和服務器B進入ESTABLISHED狀態(tài),完成三次握手。

image

 

2. 四次揮手,關(guān)閉連接

由于TCP連接是全雙工的,因此每個方向都必須單獨進行關(guān)閉。這個原則是當一方完成它的數(shù)據(jù)發(fā)送任務后就能發(fā)送一個FIN來終止這個方向的連接。

1) 客戶端A發(fā)送一個FIN,用來關(guān)閉客戶A到服務器B的數(shù)據(jù)傳送。

2) 服務器B收到這個FIN,它發(fā)回一個ACK,確認序號為收到的序號加1。和SYN一樣,一個FIN將占用一個序號。

3) 服務器B關(guān)閉與客戶端A的連接,發(fā)送一個FIN給客戶端A。

4) 客戶端A發(fā)回ACK報文確認,并將確認序號設置為收到序號加1。

image

3. 為什么建立連接協(xié)議是三次握手,而關(guān)閉連接卻是四次揮手呢?

建立連接時,服務端LISTEN狀態(tài)下的SOCKET當收到SYN報文的連接請求后,它可以把ACK和SYN放在一個報文里來發(fā)送。

關(guān)閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方?jīng)]有數(shù)據(jù)發(fā)送給你了;但未必你所有的數(shù)據(jù)都全部發(fā)送給對方了,所以你可能未必會馬上會關(guān)閉SOCKET,也即你可能還需要發(fā)送一些數(shù)據(jù)給對方之后,再發(fā)送FIN報文給對方來表示你同意現(xiàn)在可以關(guān)閉連接了,所以關(guān)閉連接的ACK報文和FIN報文多數(shù)情況下都是分開發(fā)送的。

#p#

常見的郵箱類型有哪些?

常見的郵箱類型有:免費郵箱、vip郵箱、域名郵箱、企業(yè)郵箱等等。

1. 免費郵箱

“免費郵箱”是郵件商家為任何人免費提供的電子郵件傳輸服務,作為交換,該網(wǎng)站上你請求電子郵件服務和一些個人信息的地方會顯示廣告。它更適合個人生活和娛樂的需要,卻并非那么注重郵箱的安全和功能。

部分免費郵件SMTP服務器參考設置:

span>Email類型 SMTP[Host]主服務器 Port[端口號] 是否可啟用SSL
GmailGoogle 的網(wǎng)絡郵件服務) smtp.gmail.com 587 True
HotMail/Live smtp.live.com 25 True
QQ/FoxMailFoxmail被騰訊收購) smtp.qq.com 25 False
126(網(wǎng)易) smtp.126.com 25 False
163(網(wǎng)易) smtp.163.com 25 False
Sina(新浪郵箱) smtp.sina.com 25 False
Tom smtp.tom.com 25 False
SoHu(搜狐郵箱) smtp.sohu.com 25 False
Yahoo(雅虎郵箱)(已關(guān)閉) smtp.mail.yahoo.com 25 False

2. vip郵箱

“vip郵箱”即郵件商家提供的收費版郵件服務,在速度、安全、穩(wěn)定性、容量、附件大小限制、群發(fā)數(shù)等方面相對好些。其SMTP服務器設置就是多了個vip字符。eg:smtp.vip.qq.com。郵箱地址:369220123@vip.qq.com。

3. 域名郵箱

“域名郵箱”是個性化郵件服務,能讓您用自己的域名做為后綴即“@自己的域名”,前提是你需要一個域名(通常域名要收費)。功能比免費郵箱要多:可分配單個郵箱、規(guī)劃容量、更加的安全、更好的穩(wěn)定性、個性化名稱、郵件發(fā)送量更大、附件大小限制等等。

4. 企業(yè)郵箱

“企業(yè)郵箱”是域名郵箱,但通常是指通過付費方式獲得更好服務的郵箱。eg:您公司域名為www.abc.com,則SMTP服務器為:mail.abc.com,郵箱地址:office@abc.com;

使用企業(yè)郵箱的優(yōu)勢:

1) 提升公司企業(yè)形象、郵箱穩(wěn)定性、郵箱反垃圾反病毒性能、郵件收發(fā)速度;

2) 通過購買服務,能適應企業(yè)不斷升級需求;

3) 為員工分配(域名)企業(yè)郵箱,便于將流動員工所有業(yè)務聯(lián)系保留和延續(xù)下來;

4) 監(jiān)控郵件(實際為郵件暗抄送功能),以防公司的機密和重要信息流失;

5) 獲得高性能郵件海外轉(zhuǎn)發(fā)功能,解決國際高效郵件收發(fā)、郵件營銷有效投遞等問題;

6) 出站電子郵件過濾,比如:敏感字過濾、基于政策郵件加密等等;

7) 等等。

#p#

郵件發(fā)送相關(guān).NET類庫

在 .net1.1 ,用System.Web.Mail發(fā)送郵件。在.net2.0及之后版本,用System.Net.Mail發(fā)送郵件。主要用到了在.net2.0中新增的兩個類,分別是System.Net.Mail.MailMessage和System.Net.Mail.SmtpClient兩個類,在SMTP身份驗證方面用到了System.Net.NetworkCredential類。

1. MailMessage 類表示郵件的內(nèi)容。

MailMessage常用屬性

From

MailAddress

獲取或設置此電子郵件的發(fā)信人地址。

兩者區(qū)別:當 Sender From 都有設定時,Mail Server 會取用 Sender 的設定發(fā)信,但郵件上的名稱會使用 From 的設定,而若不需要 Sender From 同時設定時,則 Sender 可以免設,但 From 一定要設。詳細請看:MailMessage Sender From? 傻傻分不清楚》

Sender

To

MailAddressCollection

獲取包含此電子郵件的收件人的地址集合。

CC

MailAddressCollection

獲取包含此電子郵件的抄送 (CC) 收件人的地址集合。

Bcc

MailAddressCollection

獲取包含此電子郵件的密件抄送 (BCC) 收件人的地址集合。

Attachments

AttachmentCollection

獲取用于存儲附加到此電子郵件的數(shù)據(jù)的附件集合。

Subject

string

獲取或設置此電子郵件的主題。

Body

string

獲取或設置郵件正文。

AlternateViews

AlternateViewCollection

指定一個電子郵件不同格式顯示的副本。(eg:發(fā)送HTML格式的郵件,可能希望同時提供郵件的純文本格式,以防止一些收件人使用的電子郵件閱讀程序無法顯示html內(nèi)容)

IsBodyHtml

bool

默認false。獲取或設置指示郵件正文是否為 Html 格式的值。

Priority

MailPriority

默認Normal。獲取或設置此電子郵件的優(yōu)先級。(Normal | Low| High)

SubjectEncoding

Encoding

獲取或設置此電子郵件的主題內(nèi)容使用的編碼。

BodyEncoding

Encoding

獲取或設置用于郵件正文的編碼。

ReplyToList

MailAddressCollection

設置接收方回復郵件時默認的接收地址,eg:你用一個郵箱發(fā)信,但卻用另一個來收信。

ReplyTo,表示單個回復地址,已過期,使用ReplyToList代替)

下面屬性想不到用在什么場景……請高人指出使用案例,謝謝!

DeliveryNotificationOptions

DeliveryNotificationOptions

默認None。獲取或設置此電子郵件的發(fā)送通知。

 

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

[Flags]

public enum DeliveryNotificationOptions

{

    // 沒有通知。

    None = 0,

    // 通知傳送是否成功。

    OnSuccess = 1,

    // 通知傳送是否失敗。

    OnFailure = 2,

    // 通知傳送是否延遲

    Delay = 4,

    // 從不通知。

    Never = 134217728,

}

 

 

 

不懂干嘛的,設置為OnSuccess,不會回復我發(fā)送成功。設置為Never,發(fā)送失敗也會回復我。。。

Headers

NameValueCollection

獲取與此電子郵件一起傳輸?shù)碾娮余]件標頭。(什么時候需要自己去設置?

HeadersEncoding

Encoding

獲取或設置此電子郵件的用戶定義的自定義標題使用的編碼。

2. SmtpClient類用于將電子郵件發(fā)送到 SMTP 服務器以便傳遞。

SmtpClient常用屬性

Host

string

獲取或設置用于 SMTP 事務的主機的名稱或 IP 地址。

Port

int

獲取或設置用于 SMTP 事務的端口。

UseDefaultCredentials

bool

默認false。

若要使用默認網(wǎng)絡憑據(jù),可以將UseDefaultCredentials設置為 true,此時System.Net.CredentialCache.DefaultCredentials(應用程序系統(tǒng)憑證)會隨請求一起發(fā)送。

如果UseDefaultCredentials屬性設置為 false,則連接到服務器時會將 Credentials 屬性中設置的值用作憑據(jù)。如果UseDefaultCredentials屬性設置為 false 并且尚未設置 Credentials 屬性,則將郵件以匿名方式發(fā)送到服務器。若SMTP 服務器要求在驗證客戶端的身份則會拋出異常。

Credentials

ICredentialsByHost

獲取或設置用于驗證發(fā)件人身份的憑據(jù)。

ClientCertificates

X509CertificateCollection

指定應該使用哪些證書來建立安全套接字層 (SSL) 連接。

EnableSsl

bool

默認false。指定SmtpClient是否使用安全套接字層 (SSL) 加密連接。

Timeout

int

默認100000.獲取或設置一個值,該值指定同步重載SmtpClient.Send()調(diào)用的超時時間。

自建本地SMTP服務器獲取郵件時需要使用的屬性:

DeliveryMethod

SmtpDeliveryMethod

默認NetworkCredential。

 

 

?

1

2

3

4

5

6

7

8

9

10

 

// 指定如何發(fā)送電子郵件。

public enum SmtpDeliveryMethod

{

    //電子郵件通過網(wǎng)絡發(fā)送到 SMTP 服務器。

    Network = 0,

    //將電子郵件復制到SmtpClient.PickupDirectoryLocation屬性指定的目錄,然后由外部應用程序傳送。

    SpecifiedPickupDirectory = 1,

    //將電子郵件復制到拾取目錄,然后通過本地 Internet 信息服務 (IIS) 傳送。

    PickupDirectoryFromIis = 2,

}

 

 

 

PickupDirectoryLocation

string

獲取或設置文件夾,應用程序在該文件夾中保存將由本地 SMTP 服務器處理的郵件。

 

下面屬性想不到用在什么場景……請高人指出使用案例,謝謝!

TargetName

string

"SMTPSVC/" + this.host。獲取或設置在使用擴展保護時用于身份驗證的服務提供程序名稱 (SPN)

ServicePoint

ServicePoint

獲取用于傳輸電子郵件的網(wǎng)絡連接。(應該會保存TCP連接,避免再次進行TCP的三次握手???)

3. 一個簡單的郵件發(fā)送示例

  1. MailMessage mail = new MailMessage();  
  2. mail.From = new MailAddress(From, FromDisplayName);  
  3. mail.To.Add(new MailAddress(To, ToDisplayName));  
  4. mail.Subject = "this is a test email.";  
  5. mail.Body = "this is my test email body.<br><b>this part is in bold</b>";  
  6. mail.IsBodyHtml = true;  
  7. SmtpClient smtp = new SmtpClient(host, port);  
  8. smtp.Credentials = new NetworkCredential(userName, password);  
  9. smtp.Send(mail); 

#p#

4. 郵件擴展:如何發(fā)送內(nèi)嵌資源(eg:圖片、mp3等等)

詳細請看:http://www.cnblogs.com/SkyD/archive/2009/05/11/1453868.html(斯克迪亞)

通過 ContentDisposition 類實現(xiàn)此功能,內(nèi)嵌的資源只做為文件內(nèi)容顯示,不再在附件列表中出現(xiàn)。ContentDisposition 類表示 MIME 協(xié)議 Content-Disposition 標頭。

對于文件附件,可以使用 ContentDisposition 的屬性來設置文件大小、文件的創(chuàng)建日期、上次讀取文件的日期以及上次修改文件的日期。對于所有附件,考慮到附件有可能會存儲到接收計算機上,可以設置一個建議的文件名。顯示電子郵件的軟件可以使用 ContentDisposition 中的信息,按發(fā)件人預期的方式呈現(xiàn)電子郵件附件。

通過 ContentDisposition 實例的Inline屬性實現(xiàn)郵件內(nèi)嵌資源。如下:

1) 設置附件的ContentId屬性為一個自定義名稱。

2) 設置附件的ContentDisposition.Inline屬性為true。

3) 在郵件的HTML格式正文中以“cid:自定義名稱”的方式引用,比如ContentId設為“face”,那么正文中就以“cid:face”作為其URL路徑字符串的替代即可。

代碼如下:(詳細見示例代碼)

  1. string picPath = Environment.CurrentDirectory + "\\附件\\PIC_Mail中文.png";  
  2. Attachment attach_pic = new Attachment(picPath);  
  3.    
  4. // 獲取或設置此附件的 MIME 內(nèi)容 ID。  
  5. attach_pic.ContentId = "MyPic";     
  6. // 實例郵件內(nèi)容  
  7. System.Net.Mime.ContentDisposition disposition = attach_pic.ContentDisposition;  
  8. // 若為內(nèi)聯(lián),則不會以附件的形式顯示,而是直接顯示為郵件內(nèi)容  
  9. disposition.Inline = true;  
  10.    
  11. FileInfo file = new FileInfo(picPath);  
  12. // 設置文件附件的創(chuàng)建日期。  
  13. disposition.CreationDate = file.CreationTime;  
  14. // 設置文件附件的修改日期。  
  15. disposition.ModificationDate = file.LastWriteTime;  
  16. // 設置文件附件的讀取日期。  
  17. disposition.ReadDate = file.LastAccessTime;  
  18. // 設定文件名稱 (內(nèi)嵌資源設置文件名后下載下來才有默認后綴)  
  19. disposition.FileName = file.Name.ToString();  
  20.    
  21. mail.AddAttachment(attach_pic); 

另外,可使用AlternateView類和LinkedResource類來實現(xiàn)內(nèi)嵌資源……

1) 創(chuàng)建一個MailMessage對象,同時指定發(fā)送人和接收人地址。

2) 創(chuàng)建AlternateView來接收文本內(nèi)容,創(chuàng)建LinkedResource來接收要嵌入的圖片或其他資源。

3) 添加LinkedResource到AlternateView

4) 添加AlternateView到MailMessage

5) 設置SmtpClient,發(fā)送email

我開發(fā)的一個發(fā)送郵件的小組件(代碼在博文開始處已給出下載地址)

為了簡化郵件發(fā)送代碼編寫和SmtpClient實例的管理,我封裝了一個發(fā)郵件的幫助類。

這個幫助類,包含如圖幾個文件:

image

兩個主要類: SmtpHelper 和MailHelper

1. SmtpHelper

此類是為了簡化構(gòu)造SmtpClient實例所需的代碼量。通過SmtpHelper構(gòu)造函數(shù)設置好SMTP服務器、端口號、身份憑據(jù),再通過鏈式操作快速設置SmtpClient其他不常使用的屬性。

Eg:

  1. SmtpClient client = new SmtpHelper( host, port, false, userName, password)  
  2.                    .SetTimeout(60*1000)  
  3.                    .SmtpClient; 

使用SmtpHelper類注意事項:

1) 非線程安全類.

2) 構(gòu)造的SmtpClient 實例外部進行Dispose()。SmtpHelper類只簡單提供構(gòu)造,不做釋放操作。

3) SmtpClient 沒有提供 Finalize() 終結(jié)器,所以GC不會進行回收,只能由外部使用完后進行顯示釋放,否則會發(fā)生內(nèi)存泄露問題.

2. MailHelper

此類完成郵件的發(fā)送工作。需要結(jié)合MailInfoHelper靜態(tài)類驗證郵件信息的有效性。

1) 支持快捷添加附件、內(nèi)嵌資源、地址信息、備用視圖格式;

Eg:添加內(nèi)嵌資源

  1. // 郵件內(nèi)容:"<a href=\"cid:MyPic\" target=\"_blank\">點擊在新窗口打開圖片</a>";  
  2. string picPath = Environment.CurrentDirectory + "\\附件\\PIC_Mail中文.png";  
  3. mail.AddInlineAttachment(picPath,"MyPic"); 

2) 支持在發(fā)送郵件前對郵件信息有效性進行檢查;

  1. Dictionary<MailInfoType, string> dic = mail.CheckSendMail();  
  2. if (dic.Count > 0 && MailInfoHelper.ExistsError(dic))  
  3. {  
  4.     // 反饋“錯誤+提示”信息  
  5.     msg = MailInfoHelper.GetMailInfoStr(dic))  
  6. }  
  7. else 
  8. {  
  9.     if (dic.Count > 0)  
  10.     {  
  11.         // 反饋“提示”信息,但還是可以發(fā)送郵件  
  12.         msg = MailInfoHelper.GetMailInfoStr(dic);  
  13.     }  
  14.      
  15.     // 發(fā)送郵件  

3) 支持批量同步、異步發(fā)送郵件

a) 批量同步發(fā)送郵件:實際上只是 SmtpClient.Send() 同步發(fā)送郵件的一個封裝。

b) 批量異步發(fā)送郵件

i. 待發(fā)送隊列:因為一個SmtpClient一次只能發(fā)送一個MailMessage,不管是同步還是異步發(fā)送,所以 SmtpClient.SendAsync() 方法后必須阻塞線程直到上一封郵件發(fā)送完成,否則會拋出“正在發(fā)送郵件”的異常。所以,MailHelper為了避免調(diào)用線程的阻塞,將待發(fā)送郵件的信息都加入到隊列中,內(nèi)部啟用一個線程去執(zhí)行串行化發(fā)送任務。

ii. 限流:“異步”批量發(fā)送過程中,為了防止待發(fā)送隊列無限制的增大,導致內(nèi)存溢出,我們可以通過MailHelper的GetAwaitMailCountAsync()方法監(jiān)控該隊列的大小,適當?shù)膱?zhí)行Thread.Sleep(time).

iii. 異步取消:可以通過MailHelper的SendAsyncCancel()方法,取消待發(fā)送隊列中的郵件繼續(xù)發(fā)送。

iv. 回調(diào)函數(shù):異步發(fā)送完一封電子郵件后執(zhí)行的回調(diào)函數(shù)。通過SendCompleted事件進行注冊。但要注意其AsyncCompletedEventArgs參數(shù)的UserState對象被改寫為了我定義的 MailUserState 對象

MailUserState定義如下:

  1. /// <summary>  
  2. /// 異步發(fā)送郵件時保存的信息,用于釋放和傳遞數(shù)據(jù)  
  3. /// </summary>  
  4. public class MailUserState  
  5. {  
  6.     #region 由MailHelper內(nèi)部的SendCompleted注冊的事件使用  
  7.     // 用于釋放 MailMessage 和 SmtpClient  
  8.     public MailMessage CurMailMessage { get; set; }  
  9.     public bool AutoReleaseSmtp { get; set; }  
  10.     public SmtpClient CurSmtpClient { get; set; }  
  11.     // 只發(fā)送單封郵件的時候使用此進行判斷釋放   
  12.     public bool IsSmpleMail { get; set; }  
  13.     #endregion  
  14.    
  15.     /// <summary>  
  16.     /// 用戶傳遞的狀態(tài)對象  
  17.     /// </summary>  
  18.     public object UserState { get; set; }  
  19.    
  20.     /// <summary>  
  21.     /// 當異步發(fā)送報錯時可通過此標識是否已經(jīng)處理該異常  
  22.     /// </summary>  
  23.     public bool IsErrorHandle { get; set; }  

批量異步發(fā)送示例(注意回調(diào)函數(shù)的用戶信息):

  1. // 設置SmtpClient的回調(diào)函數(shù)  
  2. client.SendCompleted +=(send,args) =>  
  3. {  
  4.     AsyncCompletedEventArgs arg = args;  
  5.     MailUserState userState = arg.UserState as MailUserState;  
  6. }  
  7. // 在MailHelper的構(gòu)造函數(shù)中決定是同步發(fā)送還是異步發(fā)送郵件  
  8. MailHelper mail = new MailHelper(client,true,isAsync);  
  9. for (long i = 1; i <= mailCount; i++)  
  10. {  
  11.     if(mail.GetAwaitMailCountAsync()>1000)  
  12.     {  
  13.         // 當待發(fā)送隊列大于1000時,線程休眠1秒  
  14.         Thread.Sleep(1000);  
  15.     }  
  16.         // 設置 MailHelper 發(fā)送信息  
  17.         // ……  
  18.         // 設置每封電子郵件發(fā)送完執(zhí)行回調(diào)函數(shù)的UserState  
  19.         mail.AsyncUserState = “你傳遞的對象信息”;  
  20.         // 執(zhí)行批量發(fā)送郵件  
  21.         mail.SendBatchMail();  
  22. }  
  23. mail.SetBatchMailCount(count); 

4) 批量發(fā)送郵件中,每調(diào)用一次發(fā)送方法,要使用MailHelper的Reset()對郵件內(nèi)容進行重置。

注意:

a) 不重置SmtpClient。SmtpClient根據(jù) m_autoDisposeSmtp 參數(shù)自動釋放或由外部主動釋放

b) 不重置:異步待發(fā)送隊列及隊列計數(shù)、AutoResetEvent實例、執(zhí)行異步發(fā)送線程變量、是否啟用異步發(fā)送標識變量

5) 支持自動釋放SmtpClient實例

在平常郵件開發(fā)中,當在異步批量發(fā)送郵件時,我們沒辦法掌握何時釋放我們重用的SmtpClient實例。

但,我們使用MailHelper類,可以不用關(guān)心SmtpClient的釋放問題。我們通過構(gòu)造函數(shù)中指定自動釋放SmtpClient的參數(shù)為true,并且統(tǒng)計好批量郵件發(fā)送量之后調(diào)用 SetBatchMailCount(long preCount) 方法,MailHelper就會在(批量)同步、(批量)異步郵件全部發(fā)送完之后自動釋放SmtpClient實例。

a) 為什么要“重用”同一個SmtpClient實例

因為,每次發(fā)送一封電子郵件,都必須經(jīng)過TCP的三次握手與服務器建立連接,這個連接信息就保存在SmtpClient實例中,所以當進行大批量的電子郵件發(fā)送時(前提是發(fā)件地址是相同的,當然大部分場景下發(fā)件地址都是相同的),有必要重用SmtpClient實例,避免TCP不斷地發(fā)生“三次握手和四次揮手”。

b) 為什么要“顯示釋放”SmtpClient實例

SmtpClient類沒有 Finalize (終結(jié)器)方法,因此應用程序"必須"調(diào)用 Dispose 來顯式釋放資源。 Dispose 方法在所有建立到 Host 屬性中指定的 SMTP 服務器的連接中循環(huán),并發(fā)送 QUIT 消息,其后平穩(wěn)斷開 TCP 連接。

#p#

MailHelper組件的一個示例以及幾種方式發(fā)郵件的優(yōu)劣測試

示例包含四次實驗方案和兩組復選框,如圖:

image

示例代碼下載后注意,請先修改如Config.cs文件的幾處紅色標識信息(如下圖),你才能正常發(fā)送郵件。

image

用QQ郵箱發(fā)件的注意啦,要在“設置”-“賬戶”中將“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務”服務都開啟才能正常發(fā)送郵件。如圖:

image

實驗一:單條郵件同步和異步發(fā)送(可通過添加大附件來觀察同步異步效果)

觀察:MailHelper類是如何使用的。通過大附件觀察下同步發(fā)送郵件和異步發(fā)送郵件的效果,查看下單封郵件發(fā)送

 

實驗二:批量郵件同步和異步發(fā)送(單個線程,單個SmtpClient實例,SendAsync()

觀察:MailHelper類中批量異步發(fā)送使用隊列方式實現(xiàn)的高響應性,以及批量操作如何自動釋放SmtpClient實例。觀察下

在數(shù)量較大的批量郵件發(fā)送場景中,我們可以使用多個SmtpClient(不清楚并行類庫的,請看 異步編程:.NET4.X 數(shù)據(jù)并行 實例來并行發(fā)送,以提高整體發(fā)件效率。即實驗三 + 實驗四

 

實驗三:批量郵件同步和異步發(fā)送(平行類庫Parallel(自動分區(qū)),每個分區(qū)一個MailHelperSmtpClient實例)

觀察:Parallel.For的自動分區(qū) + 每個分區(qū)一個MailHelper SmtpClient實例來提高整體效率。但是,有個問題就是自動分區(qū)又.NET內(nèi)部根據(jù)資源負載均衡自動分區(qū),分區(qū)的效果非常不好,總會開啟過多的分區(qū)導致MailHelperSmtpClient實例偏多,并且效率不高。現(xiàn)在通過

 

實驗四:批量郵件同步和異步發(fā)送(平行類庫Parallel(手動分區(qū)),每個分區(qū)一個MailHelper、SmtpClient實例)

觀察:Parallel.Foreach的手動分區(qū) + 每個分區(qū)一個MailHelper SmtpClient實例來提高整體效率。我們自己根據(jù)業(yè)務場景和Environment.ProcessorCount內(nèi)核數(shù)來決定分區(qū)數(shù),這樣可以根據(jù)需要創(chuàng)建MailHelperSmtpClient實例,并且效率非常高。在通過

 

另外:重用SmtpClient復選款的測試結(jié)果:如果只是簡單的純文本郵件發(fā)送(即,沒有耗時的附件內(nèi)容),重用SmtpClient可提升50%的效率。(注意:需要使用批量同步方式發(fā)送進行測試。因為異步方式會使用多個SmtpClient進行并行發(fā)送所以測試不出效率提升)

來個整個示例截圖:

image

本郵件發(fā)送功能分享到此結(jié)束,如果你看后覺得對你有幫助的,還請多幫推薦……推薦……如果內(nèi)容有誤的,還請幫忙指出,謝謝!

原文鏈接:http://www.cnblogs.com/heyuquan/p/net-batch-mail-send-async.html

【編輯推薦】

 

  1. 想追趕.Net的腳步?Java面前障礙重重
  2. 我也談談.NET程序員工資低
  3. 在樹莓派Raspbian下安裝支持Hard Float的.NET環(huán)境
  4. Java 與 .NET 的平臺發(fā)展之爭
  5. 基于MongoDB打造.Net的分布式Session子系統(tǒng)

 

【責任編輯:小林 TEL:(010)68476606】

責任編輯:林師授 來源: 博客園
相關(guān)推薦

2021-06-11 06:54:34

程序郵件Django

2013-05-27 13:37:42

Android開發(fā)移動開發(fā)屏幕截圖

2011-02-21 11:35:29

sendmail命令

2012-03-07 14:37:03

JavaJavaMail

2010-07-26 13:16:11

telnet pop

2011-03-23 12:55:55

Nagios郵件

2010-01-06 15:43:22

.Net Framew

2011-08-02 11:30:41

iOS開發(fā) 郵件發(fā)送

2017-04-26 09:00:23

Python發(fā)送郵件腳本

2025-04-11 08:25:36

2021-06-29 11:40:51

Python郵件命令

2024-09-23 16:43:33

.NET開發(fā)事件總線

2024-03-25 08:45:18

郵件發(fā)送Spring應用程序

2009-02-05 14:02:46

SmtpMail發(fā)送郵件ASP.NET

2010-01-19 18:06:14

VB.NET發(fā)送郵件

2020-07-27 16:52:59

Mailmerge定制郵件系統(tǒng)應用

2022-09-02 15:08:02

Python郵件發(fā)送

2022-01-28 15:04:57

Python日志郵件

2020-04-21 15:30:39

Spring Boot郵件Java

2021-03-03 06:39:05

Nodejs前端開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號

99视频在线观看视频| 亚洲一区二区三区午夜| 三上悠亚久久精品| 亚洲欧美日韩免费| 欧美mv日韩| 日韩三级av在线播放| 日本a在线免费观看| 国产中文字幕在线播放| 精品在线观看免费| 国内偷自视频区视频综合| 国产精品九九九九九| 国产毛片精品久久| 午夜精品久久久久久久久| 欧美在线激情| www.精品视频| 秋霞午夜鲁丝一区二区老狼| 欧美贵妇videos办公室| 国产123在线| 国产一区二区三区免费在线 | 欧美一级xxx| 成年人黄色片视频| 暖暖在线中文免费日本| 欧美国产一区二区| 国产精品一区二区三区四区五区| 中文无码精品一区二区三区| 亚洲黄色成人| 久久天天躁狠狠躁老女人| 可以直接看的无码av| 亚洲一区 二区| 777午夜精品免费视频| 日韩在线xxx| 超碰在线cao| 一区二区在线观看视频| 亚洲无玛一区| 国产福利小视频在线| 99久久综合99久久综合网站| 亚洲aⅴ日韩av电影在线观看| 波多野结衣毛片| 国产一区导航| 午夜精品免费视频| 久久丫精品久久丫| 亚洲乱码免费伦视频| 在线播放日韩av| 性欧美丰满熟妇xxxx性久久久| 久久69av| 日韩精品专区在线| 国产欧美精品一二三| 羞羞视频在线观看一区二区| 欧美亚州韩日在线看免费版国语版| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 91桃色在线| 亚洲欧美自拍偷拍| 亚洲天堂av免费在线观看| h网站视频在线观看| 久久精品男人的天堂| 欧美日韩中文国产一区发布| 久草视频在线看| 久久精品人人爽人人爽| 日本一区二区三不卡| 韩国三级在线观看久| 国产亚洲欧美激情| 日韩久久久久久久久久久久久| 可以在线观看的黄色| 久久免费偷拍视频| 色狠狠久久av五月综合| youjizz在线播放| 国产精品视频你懂的| 亚洲自拍的二区三区| 在线播放毛片| 亚洲精品国产一区二区三区四区在线| 久久久久久久久影视| 调教一区二区| 精品久久久视频| 18岁视频在线观看| 日韩电影精品| 日韩视频免费观看高清完整版在线观看 | 欧美激情一区二区视频| 亚洲福利免费| 国产97在线观看| 97av免费视频| 不卡视频一二三| 日产精品久久久一区二区| av在线之家电影网站| 亚洲男人的天堂网| 国产乱子伦农村叉叉叉| 欧美美女日韩| 欧美一区日本一区韩国一区| 久久久老熟女一区二区三区91| 久久91麻豆精品一区| 一区二区三区视频免费在线观看| 日韩在线不卡av| 在线成人亚洲| 国产精品日韩欧美综合| 国产suv精品一区二区69| 成人高清免费观看| 亚洲国产日韩综合一区| 免费网站在线观看人| 日韩欧美国产激情| 五月天婷婷在线观看视频| 欧美电影在线观看免费| 中文字幕在线视频日韩| 精品小视频在线观看| 日本在线不卡视频| 国产区一区二区| 99视频在线观看地址| 亚洲国产日日夜夜| 艹b视频在线观看| 全球av集中精品导航福利| 色偷偷av一区二区三区| 日韩欧美亚洲视频| 国内成人自拍视频| 日韩免费av一区二区三区| 牛牛电影国产一区二区| 欧美午夜精品久久久久久超碰 | 亚洲网一区二区三区| 国产亚洲精品久久久久动| 国产一级二级三级| 久久97超碰国产精品超碰| 蜜桃久久精品乱码一区二区 | 你懂的在线视频| 亚洲一区二区黄色| 亚洲综合伊人久久| 欧美亚洲国产一区| 欧美一区二区三区图| www.久久伊人| 亚洲免费观看视频| 99热这里只有精品在线播放| 亚洲另类春色校园小说| 欧美精品videos另类日本| 国产又黄又粗又长| 欧美国产成人在线| 黄色国产小视频| 婷婷激情久久| 8090成年在线看片午夜| 亚洲成人77777| 亚洲激情校园春色| 一区二区三区国产好的精华液| 欧美日韩伦理在线免费| 日韩av电影手机在线观看| 无码精品在线观看| 午夜精品一区二区三区免费视频| 在线免费黄色小视频| 国产精品久久久久久久久妇女| 国产精品国产亚洲伊人久久| 男同在线观看| 91福利视频久久久久| 女尊高h男高潮呻吟| 国产精品三上| 欧美极品jizzhd欧美| 成人性生活av| 国产一区二区动漫| 中文字幕在线观看你懂的| 国产拍揄自揄精品视频麻豆| 蜜臀视频一区二区三区| av永久不卡| 国产日韩欧美视频在线| 女女色综合影院| 日韩亚洲欧美综合| 国产真实夫妇交换视频| 99久久99久久综合| 国产精品-区区久久久狼 | 红桃一区二区三区| 97成人在线| 欧美一乱一性一交一视频| 飘雪影院手机免费高清版在线观看| 欧美性xxxx极品hd欧美风情| 波多野结衣av在线观看| 麻豆精品新av中文字幕| av中文字幕av| 乱亲女h秽乱长久久久| 日本一区二区不卡| 日本在线免费| 精品国一区二区三区| 亚洲午夜18毛片在线看| 日本一区二区三区免费乱视频| www.cao超碰| 欧美日韩久久| 欧美一区1区三区3区公司 | 久久久精品国产一区二区三区| 男人皇宫亚洲男人2020| www高清在线视频日韩欧美| www男人的天堂| 欧美日韩中文字幕在线| 91日韩精品一区| 欧美在线观看一区| www.xx日本| 国产成人精品一区二区三区四区| 欧美视频在线观看网站| 欧美精品一区二区久久| 亚洲伊人一本大道中文字幕| 国产夫妻在线| 日韩在线免费视频观看| 涩涩视频免费看| 欧美三级视频在线播放| 精品午夜福利视频| 欧美高清在线一区二区| 又大又长粗又爽又黄少妇视频| 香蕉视频成人在线观看| 黄瓜视频免费观看在线观看www| 成人福利一区| 成人亲热视频网站| 精品91久久| 欧美激情性做爰免费视频| 番号在线播放| 亚洲成色999久久网站| 亚洲一级片免费看| 激情懂色av一区av二区av| 国精产品一区一区二区三区mba| 91丨九色丨蝌蚪丨老版| 中文 日韩 欧美| 麻豆精品在线视频| 成人一级片网站| 精品动漫一区| 国产女主播av| 天天影视综合| 无码免费一区二区三区免费播放| 狠狠久久伊人| 99久久免费国| 96sao精品免费视频观看| 国产成人在线一区| 九色porny视频在线观看| 欧美高清视频在线| 免费a级毛片在线播放| 国产亚洲精品一区二区| 天天色综合av| 精品国产免费视频| 国产福利视频导航| 在线不卡免费av| 精品国产www| 日本精品免费观看高清观看| 日本三级一区二区| 亚洲高清不卡在线观看| 国产va在线播放| 亚洲免费av网站| 神马午夜精品91| 一区精品在线播放| 四虎影视一区二区| 国产精品久久久久一区二区三区| 亚洲天堂岛国片| 国产日韩成人精品| 少妇无套高潮一二三区| 国产欧美一区二区三区在线看蜜臀 | 欧美主播一区二区三区美女 久久精品人| 国产suv精品一区二区四区视频| 91国产在线免费观看| 在线精品自拍| 国产精品区一区二区三在线播放 | 国产三级电影在线播放| 91精品国产91久久久久久不卡| 草草视频在线| 热门国产精品亚洲第一区在线| 亚洲欧美韩国| 国产ts人妖一区二区三区| 成人午夜精品| 国产日本欧美视频| 久久视频免费| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | 久久久久久一二三区| xxxx日本免费| 国产精品久久久爽爽爽麻豆色哟哟| 我要看一级黄色录像| 亚洲精品va在线观看| 永久免费看片在线播放| 欧美性xxxxx| 在线播放成人av| 日韩一级免费一区| 四虎在线视频| 亚洲最大在线视频| 国产一二区在线观看| 久久久亚洲影院你懂的| 亚洲国产福利| 国产欧美一区二区三区久久| 激情综合五月| 久久国产精品久久精品国产| 国产一区二区在线| 中文精品一区二区三区| 激情另类综合| 粗暴91大变态调教| 国产又粗又猛又爽又黄91精品| 中国极品少妇xxxx| 国产亲近乱来精品视频| 欧美成人国产精品高潮| 日韩欧美中文在线| av片免费播放| 亚洲男人天堂2019| jizzjizz亚洲| 青青草国产精品一区二区| 午夜不卡一区| 久久人人九九| 亚洲精品va| 日本精品一区在线观看| 精品一二线国产| 鲁大师私人影院在线观看| 成人免费在线播放视频| 成年人视频在线免费看| 91精品欧美福利在线观看| 欧美偷拍视频| 九九热这里只有在线精品视| 伊人成综合网站| 99re国产视频| 红桃视频在线观看一区二区| 国产一级大片免费看| 丝袜美腿亚洲综合| 折磨小男生性器羞耻的故事| 国产精品麻豆欧美日韩ww| 日韩久久精品视频| 91精品中文字幕一区二区三区| 青青青手机在线视频观看| 九九热r在线视频精品| 99只有精品| 久久久久无码国产精品一区| 综合亚洲视频| 亚洲 欧美 另类人妖| 26uuu成人网一区二区三区| 欧美色图亚洲视频| 欧美三级日本三级少妇99| 日产精品久久久久久久性色| 欧美大片在线看| 日韩成人免费av| 亚洲 国产 欧美一区| 日韩亚洲国产欧美| 中国特级黄色片| 亚洲精品网站在线观看| 中文字幕 欧美激情| 亚洲人成网站免费播放| 麻豆理论在线观看| 国产精品区免费视频| 国产一区二区中文| 欧美xxxx黑人| 一片黄亚洲嫩模| 国产激情视频在线播放| 久久久999精品| 日韩精品第二页| 一区二区三区视频| 麻豆国产精品官网| 亚洲AV成人无码网站天堂久久| 欧美亚一区二区| 在线观看av黄网站永久| 国产女人精品视频| 97精品国产福利一区二区三区| 少妇激情一区二区三区| 久久久久88色偷偷免费| 4438国产精品一区二区| 亚洲乱亚洲乱妇无码| 欧美成人黑人| 日本精品一区| 青草av.久久免费一区| 99在线视频免费| 欧美精品日韩一本| 欧美videos极品另类| 91久久国产精品91久久性色| 亚洲成人二区| 国产精品日日摸夜夜爽| 亚洲国产精品视频| 天堂在线一二区| 日韩av电影国产| 久久福利综合| 中文字幕 欧美 日韩| 一区二区三区.www| 天天综合永久入口| 国产va免费精品高清在线观看| 精品久久影视| 手机在线国产视频| 一区二区三区国产| 无码h黄肉3d动漫在线观看| 国产97色在线|日韩| 99久久九九| 日本性生活一级片| 色呦呦网站一区| 麻豆视频网站在线观看| 99精品国产高清在线观看| 国产精品美女久久久| 337人体粉嫩噜噜噜| 日韩西西人体444www| 草草在线观看| 亚洲一二区在线| 成人一区在线看| 一级久久久久久| 欧美成人网在线| 亚洲成aⅴ人片久久青草影院| 性欧美videossex精品| 夜夜爽夜夜爽精品视频| 日韩a在线观看| 成人午夜黄色影院| 亚洲在线观看| 欧美a级片免费看| 亚洲精品在线91| 国产精品成人**免费视频| 无码精品a∨在线观看中文| 国产精品视频观看| 日韩中文字幕免费在线观看| 国产成人一区二| 女人天堂亚洲aⅴ在线观看| 熟女俱乐部一区二区视频在线| 欧美精品高清视频| 在线精品亚洲欧美日韩国产| 国产又粗又长又爽视频| 久久精品视频一区| 色窝窝无码一区二区三区| 成人精品视频久久久久|