WorkManager (How to handle multiple WorkUnits)

Eyeshot 2021 introduces a new helper class for handling a queue of WorkUnit objects.
For better understanding, we can use the term Operation to indicate the work of every single WorkUnit.
The WorkManager allows performing a single operation or all the operations one after the other synchronously or asynchronously (when an object implementing the ISupportWorkManager interface is passed as a parameter).
When running asynchronously, it notifies you when the single operation is finished or failed rather than when the queue is completed or canceled.

Here is a code snippet showing an example for loading a list of OBJ files using the WorkManager and the ReadOBJ class.

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(model1);
}

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 = model1.Entities.Count == 0;

    // Adds the content to the scene.
    ro.AddToScene(model1);


    // Fits the scene if it was empty.
    if (fit)
        model1.ZoomFit();
    
    // Refresh        
    model1.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.
}

You can find another sample code using the WorkManager class in the PaperDemo source code sample.

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.