首页 > 代码库 > 巧用CurrentThread.Name来统一标识日志记录(续)

巧用CurrentThread.Name来统一标识日志记录(续)

开篇不提前文。本文通过模拟场景来抛出问题。

我在web站点程序里新建一个tmp1.ashx文件。其类代码如下:

using System;using System.IO;using System.Threading;using System.Web;namespace PaymentPlatform.Test{    /// <summary>    /// tmp1 的摘要说明    /// </summary>    public class tmp1 : IHttpHandler    {         public tmp1()        {            Thread.CurrentThread.Name = string.Format("[{0}]",  Guid.NewGuid().ToString().Replace("-", "").ToUpper());                         WriteLog("=========");        }        public void ProcessRequest(HttpContext context)        {            context.Response.ContentType = "text/plain";             WriteLog("ProcessRequest");            context.Response.Write("1");        }        private static void WriteLog(string log)        {            string logFileName = string.Format("{0:yyyyMMdd}-{1}.txt", DateTime.Now, "Info");            logFileName = Path.Combine(System.Configuration.ConfigurationManager.AppSettings["logPath"], logFileName);            log = (System.Threading.Thread.CurrentThread.Name ?? "null") + log;            using (StreamWriter sw = new StreamWriter(logFileName, true))            {                sw.WriteLine(log);                sw.Close();            }        }        public bool IsReusable        {            get {return false; }        }    }}

 

注意,我在tmp1的构造方法里给当前线程的Name属性赋值。在后续包括ProcessRequest方法里记日志时,会获取当前线程Name并打印出来。
我做了如下几种测试:

  • ie里访问tmp1.ashx,包括频繁刷新,所记录的日志都可以获取到当前线程Name。
  • 构造Method为Get的HttpWebRequest请求,并发测试,所记录的日志都可以获取到当前线程Name。
  • 构造Method为Post的HttpWebRequest请求,在不传递参数(ContentLength=0)的情况下,并发测试,发现所记录的日志都可以获取到当前线程Name。
  • 构造Method为Post的HttpWebRequest请求,在传递参数的情况下,并发测试,发现所记录的日志都无法获取到当前线程Name。

测试用例代码如下:

 1 using CommonUtils; 2 using Microsoft.VisualStudio.TestTools.UnitTesting; 3 using System.Collections.Generic; 4 using System.IO; 5 using System.Linq; 6 using System.Net; 7 using System.Text; 8 using System.Threading; 9 10 namespace Test.TechArt11 {12     [TestClass]13     public class HttpPostTest14     {15         [TestMethod]16         public void ConcurrentTest()17         {18             for (int j = 0; j < 10; j++)19             {20                 CallASHXAPI();21             }22 23             List<Thread> list = new List<Thread>();24             for (int i = 0; i < 500; i++)25             {26                 list.Add(new Thread(() =>27                 {28                     for (int j = 0; j < 50; j++)29                     {30                         CallASHXAPI();31                     }32                 }));33             }34             list.AsParallel().ForAll(t => t.Start());35             Thread.Sleep(15000);36         }37 38         [TestMethod]39         public void CallASHXAPI()40         {41   42             string requestUrl = "http://localhost:8076/Test/tmp1.ashx";43             44             string ret = RequestUrlPost(requestUrl);45             LogHelper.Write("响应报文:" + ret);46             47         }48 49         private string RequestUrlGet(string requestUrl)50         {51             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);52             using (var reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8))53             {54                 return reader.ReadToEnd();55             }56         }57         private string RequestUrlPost(string requestUrl)58         {59             /*60              有参和无参,会导致两种结果61              */62             //无参,在tmp1.ashx的ProcessRequest的方法里记录的日志可以获取到当前线程的Name63             //string requestMsg = "";64             //有参,在tmp1.ashx的ProcessRequest的方法里记录的日志都获取不到当前线程的Name65             string requestMsg = "1";66 67             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);68             request.Method = "POST";69 70             byte[] aryBuf = Encoding.UTF8.GetBytes(requestMsg);71             request.ContentLength = aryBuf.Length;72 73             using (Stream writer = request.GetRequestStream())74             {75                 writer.Write(aryBuf, 0, aryBuf.Length);76                 writer.Close();77                 writer.Dispose();78             }79             using (var reader = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8))80             {81                 return reader.ReadToEnd();82             }83         }84     }85 }

 

由此,问题来了,Http流请求传参和不传参这两种情况有什么区别呢?

 

巧用CurrentThread.Name来统一标识日志记录(续)