简单的线程池管理器
Simple Thread Pool Manager
我想要一个线程池,我可以在其中设置线程的优先级,而且我希望它非常非常简单。下面是我写的代码。它使用存储在四个列表中的一组线程。如果没有可用线程,代码将转移到不同的线程库并调用 replenish 方法将新线程添加到没有可用线程的库中。我遇到的问题是尽管它可以执行传递的委托,但速度非常慢。关于原因有什么想法吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace xThreadPool
{
public class Pool
{
protected List<Tuple<AccessObject, Thread>>[] threadsOne;
protected List<Tuple<AccessObject, Thread>> OffLoadThreads;
private int poolSize;
protected object threadLock = new object();
protected object offLoadLock = new object();
public Pool(int size)
{
threadsOne = new List<Tuple<AccessObject, Thread>>[4];
OffLoadThreads = new List<Tuple<AccessObject, Thread>>();
poolSize = size;
for(byte x = 0;x<4;x++)
ReplenishThreads(x);
}
/// <summary>
/// Method removes any stopped threads that were off loaded when they were running to preserve them.
/// </summary>
protected void RemoveDeadThreads()
{
lock (offLoadLock)
{
foreach (Tuple<AccessObject, Thread> aThread in OffLoadThreads.ToArray())
{
if (aThread.Item2.ThreadState == ThreadState.Stopped)
{
OffLoadThreads.Remove(aThread);
}
}
}
}
/// <summary>
/// This method offloads any running threads and creates a new list to add new threads to a thread bank
/// from the array list indexed by z.
/// </summary>
/// <param name="z"></param>
protected void ReplenishThreads(byte z)
{
lock (threadLock)
{
if(threadsOne[z] != null)
{
var runningThreads = threadsOne[z].Where(x => x.Item2.ThreadState == ThreadState.Running);
lock (offLoadLock)
OffLoadThreads.AddRange(runningThreads.ToArray());
}
threadsOne[z] = new List<Tuple<AccessObject, Thread>>();
for (int x = 0; x < poolSize; x++)
{
var access = new AccessObject(x);
ThreadStart aStart = new ThreadStart(access.ExecuteMethod);
var newEntry = new Tuple<AccessObject, Thread>(access, new Thread(aStart));
newEntry.Item2.Start();
threadsOne[z].Add(newEntry);
}
Task.Run(() => RemoveDeadThreads());
}
}
/// <summary>
/// This method pushes the delegate onto a thread from a list of available threads.
/// </summary>
/// <param name="method"></param>
/// <param name="setPriority"></param>
public void Run(Action method, ThreadPriority setPriority = ThreadPriority.AboveNormal)
{
Tuple<AccessObject, Thread> aThread = default;
byte z = 0;
do
{
lock (threadLock)
{
aThread = threadsOne[z].Where(x =>x.Item2.ThreadState == ThreadState.Suspended).FirstOrDefault();
if(aThread == null)
{
Task.Run(()=>ReplenishThreads(z));
if (z < 3)
z++;
else
z = 0;
}
}
} while (aThread == null);
aThread.Item1.MethodToStart = method;
aThread.Item2.Priority = setPriority;
aThread.Item2.Resume();
}
}
/// <summary>
/// This class is used to control a thread and exection of an applied delegate
/// </summary>
public class AccessObject
{
public int ID { set; get; }
public Action MethodToStart { set; get; }
public AccessObject(int identifier)
{
ID = identifier;
}
/// <summary>
/// This is the executing method for the applied delegate MethodToStart
/// </summary>
public void ExecuteMethod()
{
Thread.CurrentThread.Suspend();
MethodToStart();
}
}
}
启动你自己的线程是昂贵的。考虑使用 ThreadPool 而不是这样做 - 您仍然可以在将作业发送到 ThreadPool 之前添加优先级队列,但不会产生启动新线程的成本。
我设法保留线程而不必补充它们,下面是代码:
/// <summary>
/// This is the executing method for the applied delegate MethodToStart
/// </summary>
public void ExecuteMethod()
{
do
{
Thread.CurrentThread.Suspend();
MethodToStart();
} while (!StopThread);
}
}
这是对 类 所做的全部更改:
public class Pool
{
protected List<AccessObject>[] threadsOne;
private int poolSize;
protected object threadLock = new object();
public Pool(int size)
{
threadsOne = new List<AccessObject>[4];
poolSize = size;
for(byte x = 0;x<4;x++)
BuildPooledThreads(x);
}
/// <summary>
/// This method creates a new list to add new threads to a thread bank
/// from the array list indexed by z.
/// </summary>
/// <param name="z"></param>
protected void BuildPooledThreads(byte z)
{
threadsOne[z] = new List<AccessObject>();
for (int x = 0; x < poolSize; x++)
{
var access = new AccessObject(x);
threadsOne[z].Add(access);
}
}
/// <summary>
/// This method pushes the delegate onto a thread from a list of available threads.
/// </summary>
/// <param name="method"></param>
/// <param name="setPriority"></param>
public void Run(Action method, ThreadPriority setPriority = ThreadPriority.AboveNormal)
{
AccessObject aThread = default;
byte z = 0;
lock (threadLock)
{
do
{
aThread = threadsOne[z].Where(x => x.StoredThread.ThreadState == ThreadState.Suspended).FirstOrDefault();
if (aThread == null)
{
if (z < 3)
z++;
else
z = 0;
}
} while (aThread == null);
aThread.MethodToStart = method;
aThread.StoredThread.Priority = setPriority;
aThread.StoredThread.Resume();
}
}
}
/// <summary>
/// This class is used to control a thread and exection of an applied delegate
/// </summary>
public class AccessObject
{
public int ID { set; get; }
public Action MethodToStart { set; get; }
public bool StopThread { set; get; }
public Thread StoredThread { private set; get; }
public AccessObject(int identifier)
{
ID = identifier;
StopThread = false;
ThreadStart aStart = new ThreadStart(ExecuteMethod);
StoredThread = new Thread(aStart);
StoredThread.Start();
}
/// <summary>
/// This is the executing method for the applied delegate MethodToStart
/// </summary>
public void ExecuteMethod()
{
do
{
Thread.CurrentThread.Suspend();
MethodToStart();
} while (!StopThread);
}
}
我想要一个线程池,我可以在其中设置线程的优先级,而且我希望它非常非常简单。下面是我写的代码。它使用存储在四个列表中的一组线程。如果没有可用线程,代码将转移到不同的线程库并调用 replenish 方法将新线程添加到没有可用线程的库中。我遇到的问题是尽管它可以执行传递的委托,但速度非常慢。关于原因有什么想法吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace xThreadPool
{
public class Pool
{
protected List<Tuple<AccessObject, Thread>>[] threadsOne;
protected List<Tuple<AccessObject, Thread>> OffLoadThreads;
private int poolSize;
protected object threadLock = new object();
protected object offLoadLock = new object();
public Pool(int size)
{
threadsOne = new List<Tuple<AccessObject, Thread>>[4];
OffLoadThreads = new List<Tuple<AccessObject, Thread>>();
poolSize = size;
for(byte x = 0;x<4;x++)
ReplenishThreads(x);
}
/// <summary>
/// Method removes any stopped threads that were off loaded when they were running to preserve them.
/// </summary>
protected void RemoveDeadThreads()
{
lock (offLoadLock)
{
foreach (Tuple<AccessObject, Thread> aThread in OffLoadThreads.ToArray())
{
if (aThread.Item2.ThreadState == ThreadState.Stopped)
{
OffLoadThreads.Remove(aThread);
}
}
}
}
/// <summary>
/// This method offloads any running threads and creates a new list to add new threads to a thread bank
/// from the array list indexed by z.
/// </summary>
/// <param name="z"></param>
protected void ReplenishThreads(byte z)
{
lock (threadLock)
{
if(threadsOne[z] != null)
{
var runningThreads = threadsOne[z].Where(x => x.Item2.ThreadState == ThreadState.Running);
lock (offLoadLock)
OffLoadThreads.AddRange(runningThreads.ToArray());
}
threadsOne[z] = new List<Tuple<AccessObject, Thread>>();
for (int x = 0; x < poolSize; x++)
{
var access = new AccessObject(x);
ThreadStart aStart = new ThreadStart(access.ExecuteMethod);
var newEntry = new Tuple<AccessObject, Thread>(access, new Thread(aStart));
newEntry.Item2.Start();
threadsOne[z].Add(newEntry);
}
Task.Run(() => RemoveDeadThreads());
}
}
/// <summary>
/// This method pushes the delegate onto a thread from a list of available threads.
/// </summary>
/// <param name="method"></param>
/// <param name="setPriority"></param>
public void Run(Action method, ThreadPriority setPriority = ThreadPriority.AboveNormal)
{
Tuple<AccessObject, Thread> aThread = default;
byte z = 0;
do
{
lock (threadLock)
{
aThread = threadsOne[z].Where(x =>x.Item2.ThreadState == ThreadState.Suspended).FirstOrDefault();
if(aThread == null)
{
Task.Run(()=>ReplenishThreads(z));
if (z < 3)
z++;
else
z = 0;
}
}
} while (aThread == null);
aThread.Item1.MethodToStart = method;
aThread.Item2.Priority = setPriority;
aThread.Item2.Resume();
}
}
/// <summary>
/// This class is used to control a thread and exection of an applied delegate
/// </summary>
public class AccessObject
{
public int ID { set; get; }
public Action MethodToStart { set; get; }
public AccessObject(int identifier)
{
ID = identifier;
}
/// <summary>
/// This is the executing method for the applied delegate MethodToStart
/// </summary>
public void ExecuteMethod()
{
Thread.CurrentThread.Suspend();
MethodToStart();
}
}
}
启动你自己的线程是昂贵的。考虑使用 ThreadPool 而不是这样做 - 您仍然可以在将作业发送到 ThreadPool 之前添加优先级队列,但不会产生启动新线程的成本。
我设法保留线程而不必补充它们,下面是代码:
/// <summary>
/// This is the executing method for the applied delegate MethodToStart
/// </summary>
public void ExecuteMethod()
{
do
{
Thread.CurrentThread.Suspend();
MethodToStart();
} while (!StopThread);
}
}
这是对 类 所做的全部更改:
public class Pool
{
protected List<AccessObject>[] threadsOne;
private int poolSize;
protected object threadLock = new object();
public Pool(int size)
{
threadsOne = new List<AccessObject>[4];
poolSize = size;
for(byte x = 0;x<4;x++)
BuildPooledThreads(x);
}
/// <summary>
/// This method creates a new list to add new threads to a thread bank
/// from the array list indexed by z.
/// </summary>
/// <param name="z"></param>
protected void BuildPooledThreads(byte z)
{
threadsOne[z] = new List<AccessObject>();
for (int x = 0; x < poolSize; x++)
{
var access = new AccessObject(x);
threadsOne[z].Add(access);
}
}
/// <summary>
/// This method pushes the delegate onto a thread from a list of available threads.
/// </summary>
/// <param name="method"></param>
/// <param name="setPriority"></param>
public void Run(Action method, ThreadPriority setPriority = ThreadPriority.AboveNormal)
{
AccessObject aThread = default;
byte z = 0;
lock (threadLock)
{
do
{
aThread = threadsOne[z].Where(x => x.StoredThread.ThreadState == ThreadState.Suspended).FirstOrDefault();
if (aThread == null)
{
if (z < 3)
z++;
else
z = 0;
}
} while (aThread == null);
aThread.MethodToStart = method;
aThread.StoredThread.Priority = setPriority;
aThread.StoredThread.Resume();
}
}
}
/// <summary>
/// This class is used to control a thread and exection of an applied delegate
/// </summary>
public class AccessObject
{
public int ID { set; get; }
public Action MethodToStart { set; get; }
public bool StopThread { set; get; }
public Thread StoredThread { private set; get; }
public AccessObject(int identifier)
{
ID = identifier;
StopThread = false;
ThreadStart aStart = new ThreadStart(ExecuteMethod);
StoredThread = new Thread(aStart);
StoredThread.Start();
}
/// <summary>
/// This is the executing method for the applied delegate MethodToStart
/// </summary>
public void ExecuteMethod()
{
do
{
Thread.CurrentThread.Suspend();
MethodToStart();
} while (!StopThread);
}
}