对于我在这里发布这么长的代码,我深表歉意,但我没有其他方法可以帮助您重现我的问题。我给你的代码当然是我正在使用的代码的缩影。我知道我可以使用 QueueUserWorkItem
并且直到最近才使用它,但我意识到我的线程太短以至于我的ThreadDispatcher
方法在第一个完成之前没有启动第二个。所以我想看看这种方式是否更快。问题是我有一个僵局,我真的不明白为什么。我正在发布您可以直接编译和重现问题的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace TestWhatever
{
public class Program
{
static MyClass ThisClass = new MyClass();
static void Main()
{
ThisClass.Start();
for (int Cnt = 0; Cnt < 5; Cnt++)
{
Console.WriteLine("Launching Frame " + Cnt);
ThisClass.Update();//Frames loop
}
}
}
public class MyClass
{
Random MyRandom = new Random();
public static object _MultiDispatcherLocker = new object();
public static bool MonoDispacherThreadLocked = true;
public static bool MultiDispacherThreadLocked = true;
// Thread pool in multithreading case
private int MaxThreadsInParallel = 5;
private static int MaxNumOfPool = 20;
private Thread[] ThreadsPool;
public static object _ThreadLockerList;
private Func<string>[] ThreadFunctions;
public bool[] ThreadLockedBools = Enumerable.Repeat(true, MaxNumOfPool).ToArray();
public void Start()
{
StartThreads();
}
public void Update()
{
lock (_MultiDispatcherLocker)
{
MultiDispacherThreadLocked = false;
Monitor.Pulse(_MultiDispatcherLocker);
}
Thread.Sleep(1000);
}
private void StartThreads()
{
ThreadsPool = new Thread[MaxNumOfPool];
_ThreadLockerList = new object();
ThreadFunctions = new Func<string>[MaxNumOfPool];
ThreadLockedBools = new bool[MaxNumOfPool];
for (int Cnt = 0; Cnt < MaxNumOfPool; Cnt++)
{
Console.WriteLine("Preparing ThreadID: " + Cnt);
ThreadLockedBools[Cnt] = true;
ThreadsPool[Cnt] = new Thread(new ParameterizedThreadStart(LaunchThread));
ThreadsPool[Cnt].Start(Cnt);
}
Thread ThreadedMainThread = new Thread(new ThreadStart(ThreadDispatcher));
ThreadedMainThread.Start();
ThreadedMainThread.Priority = System.Threading.ThreadPriority.Highest;
}
private void LaunchThread(object iThreadID)
{
int ThreadID = (int)iThreadID;
lock (_ThreadLockerList)
{
while (ThreadLockedBools[ThreadID])
Monitor.Wait(_ThreadLockerList);
}
while (true)
{
Console.WriteLine("Starting ThreadID: " + ThreadID);
ThreadFunctions[ThreadID]();
Console.WriteLine("Ending ThreadID: " + ThreadID);
lock (_MultiDispatcherLocker)
{
ThreadLockedBools[ThreadID] = true;
MultiDispacherThreadLocked = false;
Monitor.Pulse(_MultiDispatcherLocker);
}
lock (_ThreadLockerList)
{
Console.WriteLine("Blocking ThreadID: " + ThreadID);
while (ThreadLockedBools[ThreadID])
Monitor.Wait(_ThreadLockerList);
}
}
}
private void ThreadDispatcher()//object Obj)
{
lock (_MultiDispatcherLocker)
{
while (MultiDispacherThreadLocked)
Monitor.Wait(_MultiDispatcherLocker);
}
while (true)
{
for (int Cnt = 0; Cnt < 20; Cnt++)//Threads loop
{
if (RunningThreads() < MaxThreadsInParallel)
{
int CurrIntTest = MyRandom.Next(100000, 10000000);
int ThreadID = GetNextEmptyThread();
ThreadFunctions[ThreadID] = () => { MyMethodInThread(CurrIntTest); return null; };
lock (_ThreadLockerList)
{
ThreadLockedBools[ThreadID] = false;
Monitor.Pulse(_ThreadLockerList);
}
}
else//wait until someone ends
{
lock (_MultiDispatcherLocker)
{
while (MultiDispacherThreadLocked)
{
Monitor.Wait(_MultiDispatcherLocker);
}
}
}
}
lock (_MultiDispatcherLocker)
{
MultiDispacherThreadLocked = true;
while (MultiDispacherThreadLocked)
Monitor.Wait(_MultiDispatcherLocker);
}
}
}
private void MyMethodInThread(int Counter)
{
List<string> MyDummy = new List<string>();
for (int Cnt = 0; Cnt < Counter; Cnt++) MyDummy.Add("Dummy");
}
private int RunningThreads()
{
int ToReturn = 0;
for (int Cnt = 0; Cnt < MaxThreadsInParallel; Cnt++)
{
if (!ThreadLockedBools[Cnt] || ThreadsPool[Cnt].ThreadState != System.Threading.ThreadState.WaitSleepJoin)
ToReturn++;
}
return ToReturn;
}
private int GetNextEmptyThread()
{
for (int Cnt = 0; Cnt < MaxThreadsInParallel; Cnt++)
{
if (ThreadLockedBools[Cnt] && ThreadsPool[Cnt].ThreadState == System.Threading.ThreadState.WaitSleepJoin)
return Cnt;
}
return -1;
}
}
}
如果你能帮我解决这个问题,那就太好了。