开篇不提前文。本文通过模拟场景来抛出问题。
我在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 Thread.CurrentThread.Name = string.Format("[{0}]", Guid.NewGuid().ToString().Replace("-", "").ToUpper());"=========");
}
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.TechArt
11 {
12 [TestClass]
13 public class HttpPostTest
14 {
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的方法里记录的日志可以获取到当前线程的Name
63 //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流请求传参和不传参这两种情况有什么区别呢?