使用lock 语句关键字同步请求 C#
一、前言
在负责的业务中,需要后台程序定时从第三方API获取密钥,为了方便读取和管理,将密钥和密钥有效期的时间戳写入config.ini文件中。每次需要密钥时,都会先判断密钥是否在有效期内,过期即重新获取密钥【调用API的方式是使用HttpWebRequest】。
这个逻辑看似没什么问题,但在实际业务中,因为查询量的增加,会有并发获取密钥,或者相差时间非常短的多次获取密钥。密钥没失效时还没什么问题。 但是在密钥失效,重新获取密钥时,因为网络延迟或者服务器响应,会出现多个获取密钥的请求。也是因为网络波动、服务器响应,导致程序获取到密钥和时间戳的顺序不一,config.ini文件中的密钥可能最终为第一次请求的密钥。但这个密钥已经无效了,就会导致查询失败。

二、解决方法
为了使请求不会混乱,可以使用的方法很多。本文采用的是使用lock 语句关键字。这样可以保证多个请求线程的同步。只有第一个请求获取到密钥,更新完config.ini文件后,第二个请求才能执行。这样就保证了密钥总是最新的。
//lock()专用对象实例 private static readonly object thisLock = new object(); lock (LockObj) { //转换输入参数的编码类型,获取bytep[]数组 byte[] byteArray = Encoding.UTF8.GetBytes(param); //初始化新的webRequst //1. 创建httpWebRequest对象 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url)); //2. 初始化HttpWebRequest对象 webRequest.Method = "POST"; //application/x-www-form-urlencoded;charset=utf-8 webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.ContentLength = byteArray.Length; //3. 附加要POST给服务器的数据到HttpWebRequest对象 Stream newStream = webRequest.GetRequestStream(); //创建一个Stream,赋值是写入HttpWebRequest对象提供的一个stream里面 newStream.Write(byteArray, 0, byteArray.Length); newStream.Close(); //4. 读取服务器的返回信息 HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); StreamReader php = new StreamReader(response.GetResponseStream(), Encoding.UTF8); return php.ReadToEnd(); }
三、参考
c# lock的使用及注意事项
lock(this),lock(object),lock("string")区别;


浙公网安备 33010602011771号