public async Task DoWorkAsync(CancellationToken cancellationToken) { CloudQueueMessage retrievedMessage; DateTime startTime; try { // Get the next message retrievedMessage = await WorkQueue.GetMessageAsync(TimeSpan.FromHours(5), null, null, cancellationToken).ConfigureAwait(false); if (retrievedMessage == null) { return; } startTime = DateTime.UtcNow; } catch { return; } var messageContents = retrievedMessage.AsString; SlicingOptions slicingOptions = null; try { // Get the message slicingOptions = JsonConvert.DeserializeObject <SlicingOptions>(messageContents); // Make some fresh directories CreateDirectories(slicingOptions); // Populate input file locations slicingOptions.Obj = Path.Combine(inputPath, slicingOptions.Obj); slicingOptions.Texture = Path.Combine(inputPath, slicingOptions.Texture); // Track work started var workTrackingEntity = TrackWorkStarted(startTime, slicingOptions); // ** Prep Trace.TraceInformation("Syncing data"); await VerifySourceDataAsync(slicingOptions, cancellationToken); // ** Run Trace.TraceInformation("Starting Processing"); CubeManager manager = new CubeManager(slicingOptions); if (!string.IsNullOrEmpty(slicingOptions.Texture)) { slicingOptions.TextureInstance = new Texture(manager.ObjInstance, slicingOptions.Texture); } var vertexCounts = await manager.GenerateCubesForTextureTileAsync(outputPath, slicingOptions.TextureTile, slicingOptions, cancellationToken).ConfigureAwait(false); // Track work completed TrackWorkCompleted(workTrackingEntity, vertexCounts); // ** Check if set is complete CheckForComplete(slicingOptions, manager); // ** Cleanup slicingOptions.TextureInstance?.Dispose(); Trace.TraceInformation("Writing Results"); UploadResultData(slicingOptions); WorkQueue.DeleteMessage(retrievedMessage); } catch (Exception ex) { Trace.TraceError(ex.ToString()); // Release texure if we have one slicingOptions?.TextureInstance?.Dispose(); // Either delete this message or make it visible again for retry if (retrievedMessage.DequeueCount > 3) { if (slicingOptions != null) { Trace.TraceError($"Maximum Dequeue count hit for message \"{retrievedMessage.AsString}\". Failing set {slicingOptions.SetKey}"); StorageUtilities.UpdateSetFailed(TableClient, slicingOptions.SetKey, ex.ToString()); } WorkQueue.DeleteMessage(retrievedMessage); } else { WorkQueue.UpdateMessage(retrievedMessage, TimeSpan.FromSeconds(10), MessageUpdateFields.Visibility); } } finally { if (Directory.Exists(outputPath)) { Directory.Delete(outputPath, true); } if (Directory.Exists(inputPath)) { Directory.Delete(inputPath, true); } } }