关于限制,HttpWebRequest最大连接数限制
.Net中并发连接限制数量默认是2,意思就是说,哪怕你开100条线程同时进行请求,有效的连接数仍是2条,解决办法就是在App.config中修改配置.
/// <summary>
/// 测试代码
/// </summary>
public static void Test()
{
TaskPool_new _taskPool = new TaskPool_new();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
for (var i = 0; i < 20; i++)
{
_taskPool.AddTaskItem(() => Console.WriteLine("我是通过Lambda表达式创建的委托"));
}
}
public static void Test2()
{
//创建50个线程,同时执行
var taskPoo = new TaskPool_new(50);
Console.WriteLine("date ======== " + DateTime.Now.ToString("mm:ss:fff"));
// TaskPool_new _taskPool = new TaskPool_new(100);
for (var i = 0; i < 10; i++)
{
int t = i;
taskPoo.AddTaskItem(() =>
{
var delay = RandomEx.Random(50, 7900);
Thread.Sleep(delay);
Console.WriteLine("date = " + DateTime.Now.ToString("mm:ss:fff") + " ,delay =" + delay + " ,ThreadId= " + Thread.CurrentThread.ManagedThreadId + " ,i= " + t);
});
}
Console.WriteLine("date ========= " + DateTime.Now.ToString("mm:ss:fff"));
}
TaskPool_new.cs
/*
1.程序一启动就通过for循环来创建,一定数目的线程(这个数目是可以配置的)
2.至少要有三个容器来存储线程,分别是工作线程队列和空闲线程队列以及等待队列
3.使用线程中的AutoResetEvent类,初始每一个线程都是unsignaled状态,线程一启动就一直在循环调用WaitOne()方法,那么每次外部调用的时候,都调用一次这个类实例对象的set,线程然后就可以继续做下面的工作了。
4.至少两个方法:
第一个开放给外部,让外部的方法能够被传入执行,然后这个方法能够判断空闲队列,等待队列,以及工作队列的状态,如果传入的时候发现,空闲队列有空闲的线程就直接,将任务委托给空闲队列的一个线程执行,否则把它放到等待队列。
第二个方法,需要能够将工作完成的线程从工作队列移动到空闲队列,然后判断一下等待队列是不是有任务,有的话就交给空闲队列里面的线程来执行。
体思路如上,可以试试先写一下。
1.因为每个线程都有一个AutoResetEvent的实例,所以最好把Thread进行封装,变成我们自己的Thread。
*/
using System;
using System.Collections.Generic;
using System.Threading;
/// <summary>
/// 自定义线程池
/// </summary>
public class TaskPool_new
{
#region Variable
/// <summary>
/// 创建的线程数
/// </summary>
private int _threadCount;
/// <summary>
/// 空闲线程队列
/// </summary>
private Queue<Task_new> _freeQueue;
/// <summary>
/// 工作线程字典
/// </summary>
private Dictionary<string, Task_new> _workingDictionary;
/// <summary>
/// 空闲队列,存放需要被执行的外部函数
/// </summary>
private Queue<Action> _waitQueue;
#endregion
#region Event
/// <summary>
/// 自定义线程池的构造函数
/// </summary>
/// <param name="threadCount">创建的线程数</param>
public TaskPool_new(int threadCount = 10)
{
_workingDictionary = new Dictionary<string, Task_new>();
_freeQueue = new Queue<Task_new>();
_waitQueue = new Queue<Action>();
_threadCount = threadCount;
Task_new task = null;
//产生固定数目的线程
for (int i = 0; i < _threadCount; i++)
{
task = new Task_new();
//给每一个任务绑定事件
task.WorkComplete += new Action<Task_new>(WorkComplete);
//将每一个新创建的线程放入空闲队列中
_freeQueue.Enqueue(task);
}
}
/// <summary>
/// 线程任务完成之后的工作
/// </summary>
/// <param name="obj"></param>
void WorkComplete(Task_new obj)
{
lock (this)
{
//将线程从字典中排除
_workingDictionary.Remove(obj.Key);
//将该线程放入空闲队列
_freeQueue.Enqueue(obj);
//判断是否等待队列中有任务未完成
if (_waitQueue.Count > 0)
{
//取出一个任务
Action item = _waitQueue.Dequeue();
Task_new newTask = null;
//空闲队列中取出一个线程
newTask = _freeQueue.Dequeue();
// 线程执行任务
newTask._taskAction = item;
//把线程放入到工作队列当中
_workingDictionary.Add(newTask.Key, newTask);
//设置信号量
newTask.Active();
return;
}
else
{
return;
}
}
}
/// <summary>
/// 添加任务到线程池
/// </summary>
/// <param name="taskItem"></param>
public void AddTaskItem(Action taskItem)
{
lock (this)
{
Task_new task = null;
//判断空闲队列是否存在线程
if (_freeQueue.Count > 0)
{
//存在线程,取出一个线程
task = _freeQueue.Dequeue();
//将该线程放入工作队列
_workingDictionary.Add(task.Key, task);
//执行传入的任务
task._taskAction = taskItem;
//设置信号量
task.Active();
return;
}
else
{
//空闲队列中没有空闲线程,就把任务放到等待队列中
_waitQueue.Enqueue(taskItem);
return;
}
}
}
#endregion
/// <summary>
/// 测试代码
/// </summary>
public static void Test()
{
TaskPool_new _taskPool = new TaskPool_new();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
for (var i = 0; i < 20; i++)
{
_taskPool.AddTaskItem(() => Console.WriteLine("我是通过Lambda表达式创建的委托"));
}
}
public static void Test2()
{
var taskPoo = new TaskPool_new(50);
Console.WriteLine("date ======== " + DateTime.Now.ToString("mm:ss:fff"));
// TaskPool_new _taskPool = new TaskPool_new(100);
for (var i = 0; i < 10; i++)
{
int t = i;
taskPoo.AddTaskItem(() =>
{
var delay = RandomEx.Random(50, 7900);
Thread.Sleep(delay);
Console.WriteLine("date = " + DateTime.Now.ToString("mm:ss:fff") + " ,delay =" + delay + " ,ThreadId= " + Thread.CurrentThread.ManagedThreadId + " ,i= " + t);
});
}
Console.WriteLine("date ========= " + DateTime.Now.ToString("mm:ss:fff"));
}
}
public class Task_new
{
#region Variable
//一个AutoResetEvent实例
private AutoResetEvent _locks = new AutoResetEvent(false);
//一个Thread实例
private Thread _thread;
// 绑定回调方法,就是外部实际执行的任务
public Action _taskAction;
//定义一个事件用来绑定工作完成后的操作,工作队列向空闲队列移动
public event Action<Task_new> WorkComplete;
/// <summary>
///设置线程拥有的Key
/// </summary>
public string Key { get; set; }
#endregion
/// <summary>
/// 线程需要做的工作
/// </summary>
private void Work()
{
while (true)
{
//判断信号状态,如果有set那么 _locks.WaitOne()后的程序就继续执行
_locks.WaitOne();
_taskAction();
//执行事件
WorkComplete(this);
}
}
#region event
//构造函数
public Task_new()
{
_thread = new Thread(Work);
_thread.IsBackground = true;
Key = Guid.NewGuid().ToString();
//线程开始执行
_thread.Start();
}
//Set开起信号
public void Active()
{
_locks.Set();
}
#endregion
}