最近遇到一个问题,就是多个线程以相同的邮箱账号访问邮件服务器的时候登录会报错,说明多个线程不能在同一时刻用同一账号进行登录,但是不同账号之 间又互不影响,因此针对每一个不同的账号需要对其加一把锁,既可以防止报错又可以不影响其他账号登陆。方法就是新建一个dictionary,来装 object,代码如下:
1 public static bool operator !=(MailSyncFolder a, MailSyncFolder b) 2 { 3 return !(a == b); 4 } 5 6 static Dictionary<string, object> dics = new Dictionary<string, object>(); 7 public static object GetLock(string userName) 8 { 9 lock (dics) 10 { 11 if (dics.ContainsKey(userName)) 12 { 13 return dics[userName]; 14 } 15 else 16 { 17 object obj = new object(); 18 dics.Add(userName, obj); 19 return obj; 20 } 21 } 22 } 23 24 25 26 27 /// <summary> 28 /// 连接到邮箱服务器 29 /// </summary> 30 /// <returns></returns> 31 private Pop3Client ConnectToMailServer(string userName) 32 { 33 object lockObj = GetLock(userName); 34 lock (lockObj) 35 { 36 Pop3Client pop3Client = null; 37 try 38 { 39 pop3Client = new Pop3Client(); 40 pop3Client.Connect(HostIP, Port, false); 41 //pop3Client.Connect(HostIP, 110, false); 42 pop3Client.Authenticate(UserName, Password);//相同的username用锁来实现共享,不同的username不需要锁,怎么实现? 43 } 44 catch (InvalidLoginException e) 45 { 46 if (pop3Client.Connected) 47 { 48 pop3Client.Disconnect(); 49 } 50 log.Warn("The server did not accept the user credentials! POP3 Server Authentication"); 51 throw e; 52 } 53 catch (PopServerNotFoundException e) 54 { 55 if (pop3Client.Connected) 56 { 57 pop3Client.Disconnect(); 58 } 59 log.Warn("The server could not be found! POP3 Retrieval"); 60 throw e; 61 } 62 catch (PopServerLockedException e) 63 { 64 if (pop3Client.Connected) 65 { 66 pop3Client.Disconnect(); 67 } 68 log.Warn("The mailbox is locked. It might be in use or under maintenance. Are you connected elsewhere? POP3 Account Locked"); 69 throw e; 70 } 71 catch (LoginDelayException e) 72 { 73 if (pop3Client.Connected) 74 { 75 pop3Client.Disconnect(); 76 } 77 log.Warn("Login not allowed. Server enforces delay between logins. Have you connected recently? POP3 Account Login Delay"); 78 throw e; 79 } 80 catch (Exception e) 81 { 82 if (pop3Client.Connected) 83 { 84 pop3Client.Disconnect(); 85 } 86 log.Warn("Error occurred retrieving mail. " + e.Message + " POP3 Retrieval"); 87 throw e; 88 } 89 90 return pop3Client; 91 } 92 }