public void Dispose() { if (this.renderingProgressSniffer != null) { this.renderingProgressSniffer.ProgressChanged -= OnRenderProgressChanged; this.renderingProgressSniffer.Dispose(); this.renderingProgressSniffer = null; } // dispose cpu perf counter lock (this.cpuCounterLock) { if (this.cpuCounter != null) { this.cpuCounter.Close(); this.cpuCounter.Dispose(); this.cpuCounter = null; } } // dispose ram perf counter lock (this.ramCounterLock) { if (this.ramCounter != null) { this.ramCounter.Close(); this.ramCounter.Dispose(); this.ramCounter = null; } } }
private void Start(bool isRestart) { this.maxDirectory = (string)this.settings["3dsmax_dir"]; this.maxExe = (string)this.settings["3dsmax_exe"]; this.unresponsiveTimeout = TimeSpan.FromSeconds((long)this.settings["unresponsive_timeout"]); var controllerHostValue = (string)this.settings["controller_host"]; if (!IPAddress.TryParse(controllerHostValue, out this.controllerHost)) { var hostEntry = Dns.GetHostEntry(controllerHostValue); this.controllerHost = hostEntry.AddressList.FirstOrDefault(); if (this.controllerHost == null) { MessageBox.Show("Error", "Can't resolve DNS name: " + controllerHostValue, MessageBoxButtons.OK); Application.Exit(); } } //prepare startup.ms file for this worker var startupScriptFilename = Path.Combine(Path.GetTempPath(), $"worker_{this.Port}.ms"); File.WriteAllText(startupScriptFilename, $"threejsApiStart {this.Port} \"{this.controllerHost}\""); //start worker process with parameters //learn more about command line parameters here: //https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2019/ENU/3DSMax-Basics/files/GUID-1A97CFEC-60A3-4221-B9C3-5C808E2AED35-htm.html var startInfo = new ProcessStartInfo(this.maxExe, $"-ma -dfc -silent -vxs -U MAXScript {startupScriptFilename}") { WorkingDirectory = this.maxDirectory, WindowStyle = ProcessWindowStyle.Minimized }; this.Process = new Process { StartInfo = startInfo, EnableRaisingEvents = true }; //update UI if (this.Process != null) { this.Process.Exited += OnWorkerStopped; this.Process.Start(); this.Process.PriorityClass = ProcessPriorityClass.Idle; this.timerProcessCheck = new Timer(OnProcessCheckTimer, null, TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(5)); this.renderingProgressSniffer = new VrayRenderProgressSniffer(this.Process); this.renderingProgressSniffer.ProgressChanged += OnRenderProgressChanged; if (isRestart) { this.restartCount++; this.Restarted?.Invoke(this, EventArgs.Empty); } } }
private void OnWorkerStopped(object sender, EventArgs eventArgs) { this.renderingProgressSniffer.ProgressChanged -= OnRenderProgressChanged; this.renderingProgressSniffer?.Dispose(); this.renderingProgressSniffer = null; this.timerProcessCheck?.Dispose(); this.timerProcessCheck = null; var process = (Process)sender; process.Exited -= OnWorkerStopped; process.Dispose(); this.Restart(); }
public void Kill() { if (this.Process != null) { this.renderingProgressSniffer.ProgressChanged -= OnRenderProgressChanged; this.renderingProgressSniffer?.Dispose(); this.renderingProgressSniffer = null; this.timerProcessCheck?.Dispose(); this.timerProcessCheck = null; this.Process.Exited -= OnWorkerStopped; if (!this.Process.HasExited) { this.Process.Kill(); } this.Process = null; } }
//todo: Process check is SRP violation, Worker is responsible for restart private void OnProcessCheckTimer(object state) { try { if (this.Process == null || this.Process.HasExited) { return; } if (this.Process.Responding) { processUnresponsiveSince = null; } else { if (processUnresponsiveSince == null) { processUnresponsiveSince = DateTime.Now; } var unresponsiveTime = DateTime.Now.Subtract(this.processUnresponsiveSince.Value); if (unresponsiveTime > this.unresponsiveTimeout) { //kill all processes that hang longer than unresponsiveTimeout this.Process.Kill(); this.renderingProgressSniffer.ProgressChanged -= OnRenderProgressChanged; this.renderingProgressSniffer.Dispose(); this.renderingProgressSniffer = null; } } } catch (Exception) { // whatever happens here, we don't care } }