我有一个Windows服务,它以不同的时间间隔在线程中生成不同的任务。有些发生在一天一次,有些发生在每隔几分钟(就像那个给我一个问题的那个)。
我的目标是对其进行编码,以便为该任务创建一个新线程,但前提是它生成的前一个时间已经完成(或者从未创建/首次运行)。一次运行永远不应该有多个“checkThread”线程。
我还有其他区域,我使用相同的代码来检查是否应该生成新线程,这些都可以正常工作,但是其中一个我很少得到异常:
System.Threading.ThreadStateException: Thread is running or terminated; it cannot restart.
以下是在{}循环的主要部分之外定义的,用于跟踪正在发生的事情:
const int MINUTES_CHECK = 1;
DateTime lastCheck = DateTime.Now.AddMinutes(-MINUTES_CHECK); //force this to run immediately on first run
Thread checkThread; //used to poll status of thread
const int DIFFERENT_MINUTES_CHECK = 5; //maybe this one only runs every 5 minutes
DateTime different_LastCheck = DateTime.Now.AddMinutes(-DIFFERENT_MINUTES_CHECK); //force this to run immediately on first run
Thread different_checkThread; //used to poll status of thread
这是在{}循环的服务主要内部,我是如何检查是否应该创建线程。目标只是启动一个新的checkThread,如果之前从未启动过,或者前一个仍然没有运行:
// Worker thread loop
for (; ; )
{
if ((DateTime.Now - lastCheck).TotalMinutes >= MINUTES_CHECK)
{
if (checkThread == null ||
(checkThread.ThreadState != System.Threading.ThreadState.Running &&
checkThread.ThreadState != System.Threading.ThreadState.WaitSleepJoin)
)
{
checkThread = new Thread(DoCheck);
checkThread.Start();
Console.WriteLine("Checking for items...");
lastCheck = DateTime.Now;
}
}
if ((DateTime.Now - different_LastCheck).TotalMinutes >= DIFFERENT_MINUTES_CHECK)
{
if (different_checkThread== null ||
(different_checkThread.ThreadState != System.Threading.ThreadState.Running &&
different_checkThread.ThreadState != System.Threading.ThreadState.WaitSleepJoin)
)
{
different_checkThread= new Thread(DoSomethingElse);
different_checkThread.Start();
Console.WriteLine("Checking for something else...");
different_LastCheck = DateTime.Now;
}
}
//// Run this code once every N milliseconds
var wait_for = new TimeSpan(0, 0, 0, 0, 1000);
if (mStop.WaitOne(wait_for)) return;
}
它有99.9%的时间工作,到目前为止我无法在Visual Studio中实现它。我已经在VS中运行了几个小时而没有任何问题,甚至将CPU加载到99%并运行了半小时左右仍然没有得到例外。
我做了上述操作,因为我怀疑它是在尝试启动新线程并在前一个线程完成之前将其分配给“checkThread”(虽然这似乎不太可能,因为内部确实没有那么多内容“DoCheck “1分钟应该足以让它完成。”
我错过了另一个可能的ThreadState,还是还有其他事情发生?
编辑:checkThread.Start();
发生异常答案 0 :(得分:1)
当多次尝试(多于1个线程)尝试执行.Start()时,会发生此错误,您需要同步它。
是否有其他地方发出START()?
试试这个:
添加静态_syncRoot:
private static _syncRoot = new object();
同步你的开始:
if ((DateTime.Now - lastCheck).TotalMinutes >= MINUTES_CHECK)
{
if (checkThread == null ||
(checkThread.ThreadState != System.Threading.ThreadState.Running &&
checkThread.ThreadState != System.Threading.ThreadState.WaitSleepJoin)
)
{
lock( _syncRoot ) {
checkThread = new Thread(DoCheck);
checkThread.Start();
Console.WriteLine("Checking for items...");
lastCheck = DateTime.Now;
}
}
}