Soft_Job 板


LINE

最近遇到一個問題,所以上來問問看有沒有人能解惑 我們的程式有時候會進行大量發信的動作 程式語言是C#,用微軟的Exchange.WebServices元件來做發信 發信伺服器是他們公司自己架的 我們寄信為了不影響使用者操作,所以寄信都是new一個Thread來做Send Mail的動作 問題來了 有寫Log紀錄信件對象和信件內容,所以可以確認發出SendMail要求的時候傳送的資料是 正確的(信件內容、對象、認證資料等) 當信件發送量過大的時候他們信件伺服器寄出的信件的內容和對象偶爾會錯亂的情況,像 是寄給A的信件內容卻是前一封發給B的信件內容 解決方式就是改成每5秒才做一次寄信動作(之前測2、3秒還是偶爾會有問題) 第一次遇到這種情況,雖然已經解決了,但是很好奇到底是他們家伺服器問題還是什麼原 因呢? 是否有人可以解惑一下 -- 我覺得驅逐艦是艦隊裡最萌的艦種了 潛航戰正輕航重重輕▁▁▁▁ 真 其他的都應該重造 水空艦規空空巡雷巡 ██ - 。 艦戰 空母巡洋裝洋 □–□ 紳 如果各位有興趣的話可以一起成為驅逐艦 艦 母 洋艦巡艦 士 但是要經過蘿ㄏㄨ...改造 艦 洋 提 因為我們只會接受蘿莉 絕對不會接受外觀超過14歲的BBA //█◣督 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.130.11.211
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Soft_Job/M.1460103819.A.B02.html ※ 編輯: a47135 (220.130.11.211), 04/08/2016 16:24:11
1F:推 LaPass: 看起來像是執行緒安全問題 04/08 16:28
※ 編輯: a47135 (220.130.11.211), 04/08/2016 16:29:03 ※ 編輯: a47135 (220.130.11.211), 04/08/2016 16:29:24
2F:→ ken1325: 你們有做lock嗎 04/08 16:57
應該是沒有共用的部分,每封信件都是new一個Email Obj再下去做Send public void Send() { ThreadStart myRun = send_Thread; Thread myThread = new Thread(myRun); myThread.Start(); } ※ 編輯: a47135 (220.130.11.211), 04/08/2016 17:04:40
3F:推 LaPass: send_Thread 的宣告跟變動請貼出來 04/08 17:06
4F:→ manaup: 程式寫成這樣 再加上這種說明 九成九是程式有BUG 04/08 17:07
5F:→ manaup: 應該就是L大說的問題 04/08 17:09
你的意思是你覺得說明得很爛所以表示程式有問題嗎 ------程式部分 基本上就是每一封信件都是一個物件 Email mail=new Email(略) 屬性給齊之後就是mail.Send(); Eamil物件不太重要的屬性就不貼了,貼比較主要的物件內容 private static SmtpClient smtp; private MailMessage message_SMTP; /// <summary> /// 建構mail /// </summary> public Email(string strTo, List<string> strCC, string strSubject,string strBody { //strFrom一律由EmailSetting讀取 From = EmailSetting.Email_FromAddress; _To = strTo; _CC = strCC; _Subject = strSubject; _Body = strBody; } /// <summary> /// 發信 /// </summary> public void Send() { ThreadStart myRun = send_Thread; Thread myThread = new Thread(myRun); myThread.Start(); } /// <summary> /// 背景上傳寄信 /// </summary> private void send_Thread() { if (string.IsNullOrEmpty(_EMAIL_Protocol)) { _EMAIL_Protocol = FlowConfig.EmailSetting.EMAIL_Protocol; //讀取預設的發信方式 } try { //這邊是判斷寄件人收件人CC等資料有無齊全,為了不浪費各位時間就去掉了 if (flg) { Init_SMTPClient(); InitSMTP_MailMassage(); smtp.Send(message_SMTP); } } catch (SmtpException e) { //將錯誤訊息存至Windows事件日誌 string error = e.Message; ConfigApp.SystemLOG(error); } } //-----------SMTP 發信模組--------------------START-------- /// <summary> /// 初始化SMTP客戶端 /// </summary> private void Init_SMTPClient() { smtp = new SmtpClient(); smtp.Host = EmailSetting.SMTP_Server; smtp.Port = 25; //smtp.EnableSsl = true; //是否使用SSL加密 } /// <summary> /// 初始化SMTP信件內容 /// </summary> private void InitSMTP_MailMassage() { //初始化 Mail message_SMTP = new MailMessage(); message_SMTP.SubjectEncoding = Encoding.UTF8; message_SMTP.BodyEncoding = Encoding.UTF8; message_SMTP.IsBodyHtml = true; //內容使用html方式 //以下為發信的地址與顯示名稱設定 message_SMTP.From = new MailAddress(EmailSetting.Email_FromAddress, EmailSetting.Email_FromName); message_SMTP.To.Add(new MailAddress(_To)); if (_CC != null) { foreach (string s in _CC) { if (s != null && s.Length > 0) { if (_CCMode) { message_SMTP.Bcc.Add(new MailAddress(s)); } else { message_SMTP.CC.Add(new MailAddress(s)); } } } } message_SMTP.Subject = _Subject; message_SMTP.Body = _Body; } //-----------SMTP 發信模組--------------------END-------- ※ 編輯: a47135 (220.130.11.211), 04/08/2016 17:38:31
6F:推 LaPass: private [static] SmtpClient smtp; 問題可能在這裡 04/08 17:39
一開始看到你推文的時候有考慮過是不是這裡,因為看起來也就這個有可能共用到 ※ 編輯: a47135 (220.130.11.211), 04/08/2016 17:49:08
7F:推 LaPass: 你研究一下 synchronize 怎麼用,然後替smtp加上去 04/08 17:42
8F:推 LaPass: 或是乾脆把 static 拿掉,每次都重新建立一次smtp 04/08 17:44
9F:→ manaup: L大是好人 (if u r good @ sth, dont do it for free. 04/08 17:45
10F:→ LaPass: 我只有點出問題而已,這個東西要講清楚的話可是要講上好幾 04/08 17:46
11F:→ LaPass: 頁,他自己去google會比等我打出來快。 04/08 17:46
12F:推 sing10407: 答案出來了,static會在memory保留同一個記憶體位置 04/08 17:49
13F:→ sing10407: 因此用thread時會一直去改到別人的值,不是獨立的物件 04/08 17:50
14F:推 LaPass: 其實最好還是先去看一下 SmtpClient 有沒有執行緒安全 04/08 17:53
15F:→ LaPass: 他的javadoc上應該會寫,如果沒有,那應該就是這邊了 04/08 17:53
剛剛去MSDN查了一下 上面有寫 這個類型的任何公用靜態 (在 Visual Basic 中為 Shared) 成員都是安全執行緒 所以這樣說應該不是SmtpClient用static的問題? ※ 編輯: a47135 (220.130.11.211), 04/08/2016 17:57:16 ※ 編輯: a47135 (220.130.11.211), 04/08/2016 18:00:57
16F:推 LaPass: 那就..... 應該是對方的mail server或是更底層的問題了 04/08 18:02
17F:→ a47135: 的確上百家客戶就他們家會這樣XD 04/08 18:08
18F:推 sing10407: 建議先改改看 04/08 18:08
19F:→ a47135: 恩,反正那個看起來有點多餘,而且改了也不影響結果 04/08 18:16
20F:→ a47135: 還是謝謝各位的建議,至少以後程式記得會考慮這方面的問題 04/08 18:18
21F:→ a47135: XD 04/08 18:18
22F:→ a47135: 執行緒安全畢業後就變成名詞了,比較少考慮到這塊XD 04/08 18:19
23F:→ a47135: 多謝L大 04/08 18:22
24F:→ shadow0326: 呃,static members是thread-safe那句話後面還有一句 04/08 18:33
25F:→ shadow0326: instance members不保證是thread-safe 04/08 18:33
26F:→ qrtt1: InitSMTP_MailMassage 為何不直接回傳 message_SMTP 04/08 18:35
27F:→ qrtt1: 而卻是跟其他 method 共用這個變數!? 04/08 18:35
message_SMTP沒有用static,不管本身是物件屬性還是呼叫了才產生應該都沒有關係吧? 如果單純是說寫法的話.....我只能說我也是接坑的XD
28F:→ shadow0326: 你可能把那句話誤會成static SmtpClient instance是 04/08 18:36
29F:→ shadow0326: thread-safe的...那誤會可大了 04/08 18:36
我看的是中文MSDN,我中英兩邊都確認一下好了 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 18:45:20 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 18:46:11
30F:→ shadow0326: 現在是講該類別自己的成員(也就是該物件自己的state) 04/08 18:48
31F:→ shadow0326: 跟傳進的參數無關啊 04/08 18:48
我那兩句是回應qrtt1的啦XD,要回你的部分我還在看中英文MSDN看是不是我理解錯誤 貼一下中英文部分 執行緒安全 這個型別的任何 Public static (在 Visual Basic 中為 Shared) 成員都具備執行緒安全。 並非所有的執行個體成員都是安全執行緒。 Thread Safety Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe. 這意思不是說被宣告為Public static的SmtpClient具有執行緒安全 但不保證所有SmtpClient都有執行緒安全,像是沒被宣告為Public static的SmtpClient 是我理解有誤嗎(抱歉英文不很好XD) ※ 編輯: a47135 (114.32.94.97), 04/08/2016 18:53:07
32F:推 chrischen: 共用變數+race codition,問題在那堆底線開頭的變數 04/08 18:56
每封mail都是獨立new一個物件,底線開頭的變數全部都是沒用static,這樣應該不會互相 影響到吧 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:00:17 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:03:23 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:04:38 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:06:00
33F:→ x000032001: 重點是member..就是這class底下的變數 不是講他自身 04/08 19:13
34F:→ x000032001: 不是你把SmtpClient宣告public static 他就很安全了 04/08 19:14
更正,剛剛思考不足,所以把這部分回應修改了,第一反應還以為你是說Email這個class 下的成員,結果編輯完送出後發現自己耍蠢了 你的意思是,MSDN是指"SmtpClient這個class底下的變數不保證是安全執行續"的意思嗎? ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:22:07 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:34:36
35F:→ gn01838335: static 或 資源競爭 對於某事情A未處理完 04/08 19:36
36F:→ gn01838335: 被B搶走資源 沒有singleton 04/08 19:38
目前是打算寫個實例驗證一下,出幾個thread在同個時間點同時做,看看會造成什麼情況 ,然後測一下是不是static的問題 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:41:23
37F:推 gn01838335: 研判最後寄mail地方可能是關鍵,寫個log記錄 04/08 19:40
38F:→ gn01838335: 所有寄信和內容 04/08 19:41
之前都是在寄之前留log,改成寄之後再留不知道會不會有差異 ※ 編輯: a47135 (114.32.94.97), 04/08/2016 19:43:20
39F:→ gn01838335: 從這方向查感覺比較能抓到問題 04/08 19:41
40F:推 alog: 你們去買mailgun 04/08 20:26
41F:→ alog: 然後把smtp換成mailgun提供的伺服器 送送看你們所謂的大量郵 04/08 20:27
42F:→ alog: 件 04/08 20:27
43F:→ alog: 如果會出錯 是你們程式錯 如果沒有錯 就是對方的smtp server 04/08 20:28
44F:→ alog: 有問題 04/08 20:28
我們有買hibox,同樣資料有用hibox測試過,是沒有問題的 基本上所有客戶到現在同樣的程式就他們家會有這個問題 大概我接手三年遇過兩次(含這次) ※ 編輯: a47135 (114.32.94.97), 04/08/2016 20:30:40
45F:→ alog: 看一下email source code有沒有email server版本 04/09 00:58
46F:→ alog: *smtp 版本資訊 04/09 00:58
47F:→ alog: 然後在搜尋一下是不是他們smtp server是不是版本沒更新 04/09 00:59
48F:→ alog: 或看這軟體有沒有changelog有記載這類問題的 04/09 00:59
49F:→ chrischen: 沒貼完整code 用猜的看不準 丟到github公開review吧 04/09 09:02
50F:推 lovdkkkk: 這寫法它是 thread safe 也沒有用啊 0rz 04/09 10:38
51F:→ lovdkkkk: 在 Init_SMTPClient 它會不斷地被換成新的實體 04/09 10:49
52F:→ lovdkkkk: 要寫 log 直接開 smtp 本身的送信記錄 log 最準 04/09 10:51
53F:→ lovdkkkk: 要測可以把間隔縮成 0 秒看別家會不會也出問題 XD 04/09 10:52
54F:→ evanslify: 直覺覺得, 你踩到雷; 如果間隔0會不會100%出錯? 04/09 17:48
禮拜一打算寫支測試試看看w ※ 編輯: a47135 (114.32.94.97), 04/09/2016 18:49:56
55F:推 brucetu: log應該留在最後面,現在這樣不是等於白留了嗎? 04/09 20:20
56F:→ brucetu: 還有為什麼不改成固定用一個thread發就好,要每一個寄信 04/09 20:22
57F:→ brucetu: 動作都用一個新的thread呢 徒增race condiction的可能性 04/09 20:22
58F:→ brucetu: 沒有信要送的時候就sleep,耗用的資源基本是0 04/09 20:23
59F:→ brucetu: 另外… 上個跟list傳值有關的解釋The澑eference湶s pass 04/09 20:43
60F:推 brucetu: The澑eference湶s passed毪y value.Arrays in .NET are o 04/09 20:46
61F:推 brucetu: The reference is passed by value 04/09 20:50
62F:→ brucetu: Arrays in .net are object on the heap 04/09 20:50
63F:→ brucetu: , so you have a reference. That reference is passed b 04/09 20:51
64F:→ brucetu: y value, meaning that changes to the氲ontents漑f the 04/09 20:51
65F:推 brucetu: meaning that changes to the contrnts of the array wil 04/09 20:53
66F:→ brucetu: l be seen by the caller ,but reassigning the array wo 04/09 20:53
67F:→ brucetu: nt. 04/09 20:53
68F:→ brucetu: 似乎代表著,你建構一個mail,傳cc的list 進去之後,呼叫 04/09 20:53
69F:→ brucetu: send start一 04/09 20:53
70F:→ brucetu: 呼叫 mail.send ,start 一個new thread,接著讀取下一份 04/09 20:54
71F:→ brucetu: 資料,準備建構新的mail,這時如果外層沒有assign一個新 04/09 20:54
72F:→ brucetu: 的list給cc,而是把原本的ccList直接clear再add ,就會 04/09 20:54
73F:→ brucetu: 修改到前一個mail的_cc 因為都是指向同一個list,所以在m 04/09 20:54
74F:→ brucetu: ail建構的那邊應該對list做個clone比較安全,雖然你不一 04/09 20:54
75F:→ brucetu: 定會碰到這個問題發生。我還是覺得用一條線程去發就好了 04/09 20:54
76F:→ brucetu: … 04/09 20:54
77F:→ lovdkkkk: 同樓上, 一條慢慢的一封一封寄就好了 @@ 04/09 20:56
78F:→ brucetu: 只用一條線程循環處理所有要寄的信 也不會多慢吧,絕對 04/09 21:57
79F:→ brucetu: 比現在五秒發一封快,不然就是好好檢查把資料傳遞切乾淨 04/09 21:57
80F:→ brucetu: ,也許其他客戶沒有出問題是因為他們沒發現?例如根本沒 04/09 21:57
81F:→ brucetu: 有check或者訊息內容非常雷同 寄錯人也不會發現 04/09 21:57
82F:推 psliurt: 哀 問題就是那個static smtpclient 04/10 12:48
83F:→ psliurt: 我覺得你先把執行緒跟何謂執行緒安全搞清楚 04/10 12:51
84F:推 YahooTaiwan: 既然每次送信都要 new smtpclient,幹嘛放 static ?? 04/10 19:02
85F:→ YahooTaiwan: ? 04/10 19:02
86F:→ YahooTaiwan: 感覺你不是很了解 static 的特性與用途 04/10 19:03
我也只是個接坑的XD 不可能到手的案子都一行一行看吧,也只能有出現問題再來琢磨了,所以前面有人這樣 說過我也是回他我也覺得這感覺沒啥意義 ※ 編輯: a47135 (114.32.94.97), 04/10/2016 21:06:43 最後爭取(說服?)上面的 把整個系統的發信系統改成Queue起來慢慢寄 ※ 編輯: a47135 (220.130.11.211), 07/28/2016 09:31:42







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:iOS站內搜尋

TOP