Code sample: Suspending and waking up of ACThread
public class MyWorkerComp : PAClassAlarmingBase
{
protected SyncQueueEvents _SyncEvent;
private ACThread _WorkCycleThread;
public MyWorkerComp(ACClass acType, IACObject content, IACObject parentACObject, ACValueList parameter, string acIdentifier = "")
: base(acType, content, parentACObject, parameter, acIdentifier)
{
// 1. Use ManualResetEvent as a thread synchronization element for shutting down a thread
_SyncEvent = new SyncQueueEvents();
// 2. Create a new thread-instance
_WorkCycleThread = new ACThread(RunWorkCycle);
}
public override bool ACInit(Global.ACStartTypes startChildMode = Global.ACStartTypes.Automatic)
{
bool result = base.ACInit(startChildMode);
// 3. Name-Property should contain a unique Identifier. e.g. with a ACUrl:
_WorkCycleThread.Name = "ACUrl:" + this.GetACUrl() + ";RunWorkCycle();";
_WorkCycleThread.Start();
return result;
}
public override bool ACDeInit(bool deleteACClassTask = false)
{
bool result = base.ACDeInit(deleteACClassTask);
if (_WorkCycleThread != null)
{
// 10. Wakes up thread for executing DoSomething()
// and stops the loop inside RunWorkCycle() afterwards
_SyncEvent.TerminateThread();
// 12. The Join-Method waits until RunWorkCycle()-Method has breaked its loop and ThreadTerminated() was invoked.
_WorkCycleThread.Join();
_WorkCycleThread = null;
_SyncEvent = null;
}
return result;
}
private void RunWorkCycle()
{
try
{
// 4. Make a endless loop that only breaks if TerminateThread()-Signal is set from ACDeInit.
while (!_SyncEvent.ExitThreadEvent.WaitOne(0, false))
{
// 5. Suspend this thread and wait for wakeup from ActivateThreadForDoSomething() or from TerminateThread().
_SyncEvent.NewItemEvent.WaitOne();
// 7. Call this method for measuring the execution time of your custom code.
// It's used by the PerformanceLogger-Class that reports statistics to the RuntimeDump-Class.
_WorkCycleThread.StartReportingExeTime();
// 8. Invoke your custom code
DoSomething();
// 9. Stop Measuring the execution time of this thread.
_WorkCycleThread.StopReportingExeTime();
}
}
catch (ThreadAbortException e)
{
Messages.LogException(this.GetACUrl(), "RunWorkCycle()", e);
}
// 11. Report ACDeInit
_SyncEvent.ThreadTerminated();
}
private void DoSomething() { }
public void ActivateThreadForDoSomething()
{
if (!_SyncEvent.NewItemsEnqueueable)
return;
// 6. Wakeup thread for executing DoSomething()
_SyncEvent.NewItemEvent.Set();
}
}
Modifier: Aleksandar Agincic / Modified:25.01.2021 10:51