我有一个应用程序,该应用程序将旋转线程列表,然后将它们接一个地踢开,直到达到预定义的线程限制,一旦发生这种情况,它将等到线程完成在开始另一个之前。我想实现一种方法,以退出当前正在运行的所有线程,如果达到连续错误的阈值。我已经清除了要处理的线程列表,因此将不再启动,但是我不确定如何关闭一旦达到线程限制的剩余线程,我都知道一个线程可以't与另一个人交谈,这就是我被挂断的地方..我提供了下面的主要方法。
public static void Run(string distinguishedName, string hrExtractFile, string sanctionsFileLocation, string exemptionsFileLocation, string url, string soapAction, int threadLimit)
{
UsersList Employees = new UsersList(distinguishedName, hrExtractFile); //imports users from HR file
int errorcount = 0;
ManualResetEvent resetEventThreadComplete = new ManualResetEvent(false);
ManualResetEvent resetEventNoMoreThreads = new ManualResetEvent(false);
List<Thread> threads = new List<Thread>();
int toProcess = Employees.Count;
for (int i = 0; i < Employees.Count; i++)
{
int current = i;
threads.Add(new Thread(delegate ()
{
User u = Employees[current];
User drUser = new User();
try
{
drUser = fetchUser(u, url, soapAction);
bool userExists = false;
if (drUser != null)
{
userExists = true;
}
//removes a user if they're in the deleted users OU as well as being in system
if (u.IsDeleted)
{
if (userExists == true)
{
Console.WriteLine("Removing " + u.AccountName);
Log.writeToLogs("activitylog.txt", "Removing " + u.AccountName + ":", u, drUser);
DeleteUser(u, url, soapAction);
}
}
errorcount = 0;
}
}
catch (Exception e)
{
if (errorcount <= 5)
{
Log.writeToLogs("syslog.txt", e.ToString());
Log.writeToLogs("activitylog.txt", u.AccountName + " - Failed to true up!");
Console.WriteLine("Failed on " + u.AccountName + ": An error occured, check logs for details");
errorcount++;
}
else
{
lock (_syncObject)
{
//removes threads from list of threads that are pending
if (threads.Count > 0)
{
threads.Clear();
}
}
}
}
resetEventThreadComplete.Set();
if (Interlocked.Decrement(ref toProcess) == 0)
resetEventNoMoreThreads.Set();
}));
}
/*
* Kicks off the first x number of threads (where x = threadLimit) and removes them from list of pending threads
*/
for (int i = 0; i < threadLimit; i++)
{
if (threads.Count < 1)
break;
//runningThreads++;
threads[0].Start();
threads.RemoveAt(0);
}
/*
*Controls the initiation of thread exection; When one thread finishes, another will be started and removed from the list of pending threads
*/
while (threads.Count > 0)
{
resetEventThreadComplete.WaitOne();
resetEventThreadComplete.Reset();
threads[0].Start();
threads.RemoveAt(0);
}
if (toProcess > 0) resetEventNoMoreThreads.WaitOne();
//Log.sendLogs();
}
假设您不介意杀死线程(通常不是一个好主意),则可以在清除列表之前使用类似的代码:
if (threads.Count > 0)
{
threads.ForEach(t => t.Abort()); //Kill all threads
threads.Clear();
}
话虽如此,如果您相信此海报:
,您可能不应该使用thread.abort()您是否读过MSDN上的"备注"部分?切勿使用中断。它是最后的度假胜地。如果您使用线程。射击,天空可能会掉下来,小猫将被杀死
无论您选择哪种方法,都可以将其放入ForEach
表达式中,例如如果您喜欢使用Interrupt
:
threads.ForEach(t => t.Interrupt());
另一种(更简单)的方法是修改线程以检查全局标志变量并在设置时干净地退出。在您的主要程序中,当您希望杀死线程时,只需设置标志即可。确保使用挥发性变量,或者更好,或者更好。