using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace new爬虫 { public partial class 采集 : Form { public static 采集 main; public string resultToken; public static string content = ""; public static int maxThread = 10; public static int minThread = 10; delegate void SetTextCallback(string text); public 采集() { InitializeComponent(); this.richTextBox1.Text = "采集初始化成功."; this.textBox执行次数.Text = "100"; this.textBox最大线程数.Text = "10"; this.textBox最小线程数.Text = "10"; Helper.fileToString(); main = this; } /// <summary> /// 开始采集 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { for (int i = 0; i < 1; i++) { ThreadStart threadStart = new ThreadStart(upload);//通过ThreadStart委托告诉子线程执行什么方法 Thread thread = new Thread(threadStart); thread.Start();//启动新线程 } #region 线程池测试 //int min, max, count; //try //{ // min = int.Parse(this.textBox最小线程数.Text); // max = int.Parse(this.textBox最大线程数.Text); // count = int.Parse(this.textBox执行次数.Text); //} //catch { MessageBox.Show("数据格式输入非整数");return; } //ThreadPool.SetMinThreads(min, min); //ThreadPool.SetMaxThreads(max, max); //for (int i = 1; i <= int.Parse(this.textBox执行次数.Text); i++) //{ // ThreadPool.QueueUserWorkItem(new WaitCallback(upload), content); //} #endregion } /// <summary> /// 上传 /// </summary> /// <param name="obj"></param> private static void upload(object obj) { httplogin.HttpHelper(obj.ToString()); } private static void upload() { httplogin.HttpHelper(""); } /// <summary> /// 添加 /// </summary> /// <param name="info"></param> public void addLog(string info) { this.richTextBox1.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ") + info + " " + this.richTextBox1.Text; } public void SetText(string text) { //子线程睡眠1秒 //Thread.Sleep(1000); if (this.richTextBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.richTextBox1.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ") + text + " " + this.richTextBox1.Text; this.richTextBox1.Refresh(); } } private void button2_Click(object sender, EventArgs e) { this.richTextBox1.Text = ""; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; namespace new爬虫 { public class httplogin { /// <summary> /// Token /// </summary> public static string Token; public static string url; /// <summary> /// 登录 /// </summary> public static async void HttpHelper(string resultJson) { 采集.main.SetText(Thread.CurrentThread.ManagedThreadId.ToString() + "号线程开启"); Helper.AddLogMsg("上传线程开启时间", "当前线程号:" + Thread.CurrentThread.ManagedThreadId); //记录开始时间 DateTime start= DateTime.Now; HttpResponseMessage responseMessage = new HttpResponseMessage(); HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token); HttpContent httpContent = new StringContent(resultJson); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); string result = ""; HttpResponseMessage httpResponseMessage = new HttpResponseMessage() ; try { start = DateTime.Now; httpResponseMessage = await httpClient.PostAsync(url, httpContent); if (httpResponseMessage != null && responseMessage.IsSuccessStatusCode && responseMessage.StatusCode == HttpStatusCode.OK) { result = "上传成功"; //成功的逻辑处理 //Helper.AddLogMsg("上传成功", "当前线程号:" + Thread.CurrentThread.ManagedThreadId); } else { result = "上传失败"; //Helper.AddLogMsg("上传失败", "当前线程号:" + Thread.CurrentThread.ManagedThreadId); } } catch { /* Helper.AddLogMsg("上传失败", "当前线程号:" + Thread.CurrentThread.ManagedThreadId);*/ result = "上传失败"; } finally { httpResponseMessage.Dispose(); httpClient.Dispose(); responseMessage.Dispose(); } //记录接触时间 var interval = (DateTime.Now - start).TotalMilliseconds; 采集.main.SetText(Thread.CurrentThread.ManagedThreadId.ToString() + "号线程结束 耗时: " + interval + "ms " + result+" "); Helper.AddLogMsg("上传线程关闭时间", "当前线程号:" + Thread.CurrentThread.ManagedThreadId + " 耗时:" + interval + "ms " + result + " url:"+ url); } /// <summary> /// 执行时间 /// </summary> /// <returns></returns> //private static string dealTime() //{ //} } }
这是两个主要的逻辑代码 对于运行结果
单线程
线程池
关于这个问题 我尝试用了穷举法看到底是什么地方出现了问题
有以下猜测
1.关于单次执行耗时较少问题 不需要考虑cpu轮转执行片段切换线程 并且创建底层所需要的单例对象 所以第一次耗时相对单线程 较多
2.对于线程池 第一次执行耗时较长 是因为 线程创建耗时 线程轮转切换耗时 底层创建单例静态资源块忽略(因为被哪一个线程执行 并不确定)
3.关于线程池里面的线程创建回收线程 是否保存当前线程块的资源 尚不确定(存在疑问 大佬可以帮忙解释一下)
4.不存在线程池的回收线程的线程都将被销毁
124已被猜想证实 3回收线程 尚未查到