Reputation: 3880
I have created a ThreadManager
class that handles Threads
and its task is to add new threads
and clean up the dead threads
. However, the threads
that are created remain alive and in ThreadState.WaitSleepJoin
state. I have checked that the body has successfully finished execution. Any ideas?
public bool TryAddThread(ThreadStart threadBody, ThreadStartInfo startInfo)
{
bool success = false;
// Validate arguments
if (threadBody == null || startInfo == null)
{
return false;
}
if (!Monitor.TryEnter(_lock) || !_allowNewThreads)
{
return false;
}
try
{
Thread newThread = new Thread(threadBody);
StartThread(newThread, null, startInfo);
success = true;
}
finally
{
Monitor.Exit(_lock);
}
return success;
}
private void StartThread(Thread newThread, object threadParams, ThreadStartInfo startInfo)
{
if (newThread == null || startInfo == null)
{
return;
}
// Apply start info
newThread.Name = startInfo.Name;
newThread.SetApartmentState(startInfo.ApartmentState);
newThread.IsBackground = startInfo.IsBackground;
if (threadParams == null)
{
newThread.Start();
}
else
{
newThread.Start(threadParams);
}
_threads.Add(newThread);
RemoveDeadThreads();
}
public void RemoveDeadThreads()
{
_threads.RemoveAll(t => (!t.IsAlive));
}
Execution in main thread:
public void InsertAsync(AP p, APr pr)
{
ParameterizedThreadStart thread = new ParameterizedThreadStart(InsertPr);
List<object> parameters = new List<object>();
// Create new controller. Must be before the thread to avoid cross-thread operation exception.
PageController controller = new PageController();
controller.Initialize(siteWebBrowser);
parameters.Add(controller);
parameters.Add(p);
parameters.Add(pr);
parameters.Add(_session);
// If the thread cannot start notify listeners
if (!_threadManager.TryAddThread(thread, parameters, new ThreadStartInfo("InsertAsync", ApartmentState.STA, true)) && ThreadCreationFailed != null)
{
_logger.Error("InsertAsync: Could not start thread.");
ThreadCreationFailed();
}
}
private static void InsertPr(object o)
{
try
{
_logger.Debug("Thread start - InsertPr");
List<object> parameters = (List<object>)o;
PageController controller = (PageController)parameters[0];
AP p = (AP)parameters[1];
APr pr = (APr)parameters[2];
Session session = (Session)parameters[3];
if (patient == null)
{
throw new ArgumentException("Null patient.");
}
session.WaitForHistorySynchronizationSuspension();
if (Program.ShouldAbortBackgroundOperations)
{
throw new Exception("Aborting..");
}
session.DoingSomeJob = true;
controller.ClearCurrent();
controller.GoToHomePage(3, true);
controller.ClickNew();
controller.SearchForP(p.Id);
try
{
controller.WaitUntilDivExists(Constants.NewPrContainerDivId);
}
catch (Exception)
{
_logger.Error("InsertAsync: Error while waiting for div '" + Constants.NewPrContainerDivId + "' to appear.");
throw;
}
if (PrInsertionCompleted != null)
{
PrInsertionCompleted();
}
}
catch (Exception ex)
{
_logger.ErrorException("InsertAsync", ex);
if (InsertionFailed != null)
{
InsertionFailed(Constants.MessageFailed);
}
}
}
Upvotes: 1
Views: 1895
Reputation: 941455
You can ask the CLR to automatically abort threads for you when the main startup thread of the program terminates. But that's not automatic, you have to explicitly set the thread's IsBackground property to true. Threadpool threads have that property turned on automatically.
Upvotes: 2
Reputation: 35881
WaitSleepJoin means the thread has blocked itself with a call to lock (Monitor.Enter), a call to Thread.Sleep, or a call to Thread.Join, or some other thread synchronization object.
Maybe if you provide example thread entry point that is causing this thread state, someone can provide a more detailed answer.
Upvotes: 1