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 + "\n" + 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 + "\n" + 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 + " \r\n 耗时:" + interval + "ms \r\n " + result + "\r\n url:"+ url); } /// <summary> /// 执行时间 /// </summary> /// <returns></returns> //private static string dealTime() //{ //} } }
这是两个主要的逻辑代码 对于运行结果

单线程

线程池
关于这个问题 我尝试用了穷举法看到底是什么地方出现了问题
有以下猜测
1.关于单次执行耗时较少问题 不需要考虑cpu轮转执行片段切换线程 并且创建底层所需要的单例对象 所以第一次耗时相对单线程 较多
2.对于线程池 第一次执行耗时较长 是因为 线程创建耗时 线程轮转切换耗时 底层创建单例静态资源块忽略(因为被哪一个线程执行 并不确定)
3.关于线程池里面的线程创建回收线程 是否保存当前线程块的资源 尚不确定(存在疑问 大佬可以帮忙解释一下)
4.不存在线程池的回收线程的线程都将被销毁
124已被猜想证实 3回收线程 尚未查到
posted on
浙公网安备 33010602011771号