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/cn.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灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP