Eyeshot 2021 introduces a new helper class designed to handle a queue of WorkUnit objects more efficiently.
To facilitate understanding, we use the term Operation to refer to the work carried out by each individual WorkUnit.
The WorkManager class enables the execution of either a single operation or all operations in the queue, either synchronously or asynchronously. If an object that implements the ISupportWorkManager interface is provided as a parameter, asynchronous execution becomes possible.
In asynchronous mode, you receive notifications about the completion or failure of each individual operation, rather than waiting for the entire queue to finish or be canceled.
Below is a code snippet that illustrates an example of loading a list of OBJ files using the WorkManager and the ReadOBJ classes.
private WorkManager<ReadOBJ> _readMultiObj;
private void ReadObjFiles(string[] filePaths)
{
// Creates the WorkManager if needed
if (_readMultiObj == null)
{
_readMultiObj = new WorkManager<ReadOBJ>();
// Listens to WorkManager events
_readMultiObj.WorkUnitCompleted += ReadMultiObj_WorkUnitCompleted;
_readMultiObj.WorkUnitFailed += ReadMultiObj_WorkUnitFailed;
_readMultiObj.QueueCompleted += ReadMultiObj_QueueCompleted;
_readMultiObj.QueueCancelled += ReadMultiObj_QueueCancelled;
}
// Appends a reader for each file
for (int i = 0; i < filePaths.Length; i++)
_readMultiObj.AppendToQueue(new ReadOBJ(filePaths[i]));
// Runs all the operations asynchronous if the WorkManager is not running yet.
_readMultiObj.RunAll(design1);
}
private void ReadMultiObj_WorkUnitCompleted(object sender, WorkUnitEventArgs e)
{
// Operation completed
Debug.Assert(e.WorkUnit.Status == workUnitStatus.Completed);
ReadOBJ ro = (ReadOBJ) e.WorkUnit;
// Adds here some logic for checking ReadOBJ content (e.g. applying transformations to the entities).
bool fit = design1.Entities.Count == 0;
// Adds the content to the scene.
ro.AddTo(design1);
// Fits the scene if it was empty.
if (fit)
design1.ZoomFit();
// Refresh
design1.Invalidate();
// You can choose to remove the WorkUnit to free-up memory.
_readMultiObj.RemoveFromQueue(ro);
}
private void ReadMultiObj_WorkUnitFailed(object sender, WorkUnitEventArgs e)
{
// Operation Failed
Debug.Assert(e.WorkUnit.Status == workUnitStatus.Failed);
WriteLog(e.WorkUnit.Log);
}
private void ReadMultiObj_QueueCompleted(object sender, EventArgs e)
{
// All Operations completed
// Removes event handlers
_readMultiObj.WorkUnitCompleted -= ReadMultiObj_WorkUnitCompleted;
_readMultiObj.WorkUnitFailed -= ReadMultiObj_WorkUnitFailed;
_readMultiObj.QueueCompleted -= ReadMultiObj_QueueCompleted;
_readMultiObj.QueueCancelled -= ReadMultiObj_QueueCancelled;
// Dispose the WorkManager
_readMultiObj.Dispose();
_readMultiObj = null;
}
private void ReadMultiObj_QueueCancelled(object sender, WorkUnitEventArgs e)
{
// Operation Cancelled
Debug.Assert(e.WorkUnit.Status == workUnitStatus.Cancelled);
// When the WorkManager starts again, it will get the first WorkUnit with status Idle or Cancelled.
}
private void WriteLog(string message)
{
// Code for logging here.
}
In the PaperDemo source code sample, you can find another example of how to use the WorkManager class.
Comments
Please sign in to leave a comment.