我有一个代码,应该启动一个进程来渲染动画。它工作得很好并且启动了所有过程,但是当过程运行时,我的程序说没有响应,并且冻结拒绝更新进度。
以下是应该导致此问题的代码:
void Render()
{
while (currentFrame <= lastFrame)
{
bool rendering = IsRendering("cmd");
if (rendering == false)
{
StreamWriter renderBatch = new StreamWriter(batchFile);
renderBatch.Write('"' + renderPathField.Text + '"' + " -rd " + '"' + imagePath.Text + '"' + " -s " + currentFrame + " -e " + currentFrame + " " + '"' + sceneFile.Text + '"');
renderBatch.Close();
var renderProcess = new Process();
renderProcess.StartInfo = new ProcessStartInfo(batchFile);
//renderProcess.StartInfo.Arguments = '"' + renderPathField.Text + '"' + " -rd " + '"' + imagePath.Text + '"' + " -s " + currentFrame + " -e " + currentFrame + " " + '"' + sceneFile.Text + '"';
renderProcess.StartInfo.UseShellExecute = false;
//renderProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
renderProcess.Start();
if (renderProcess.HasExited == true && currentFrame < lastFrame)
{
ProgressBar1.Value = (currentFrame - 1) / lastFrame;
currentFrame++; //goes onto the next frame once it is done rendering this frame
}
}
}
}
以下是它的完整代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//using System.Net;
using System.Diagnostics;
using System.IO;
namespace Maya_Network_Render
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Globals ///////////////////////////////////////
string prefFile = "C:\\Program Files\\Maya Render Buddy Preferences\\options.txt";
string batchFile = "C:\\Program Files\\Maya Render Buddy Preferences\\render.bat";
int firstFrame;
int lastFrame;
int currentFrame;
// Globals //////////////////////////////////////
private void Form1_Load(object sender, EventArgs e)
{
if (Directory.Exists("C:\\Program Files\\Maya Render Buddy Preferences"))
{
if (File.Exists(prefFile))
{
StreamReader preferences = new StreamReader(prefFile);
string renderFilePath = preferences.ReadLine();
renderPathField.Text = renderFilePath;
preferences.Close();
}
else
{
File.Create(prefFile);
}
}
else
{
Directory.CreateDirectory("C:\\Program Files\\Maya Render Buddy Preferences");
File.Create(prefFile);
}
}
private void sceneBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog scenefinder = new OpenFileDialog();
scenefinder.Title = "Browse to your Maya scene file";
scenefinder.RestoreDirectory = true;
if (scenefinder.ShowDialog() == DialogResult.OK)
{
sceneFile.Text = scenefinder.FileName;
}
}
private void imageBrowse_Click(object sender, EventArgs e)
{
FolderBrowserDialog imageFolderSelection = new FolderBrowserDialog();
imageFolderSelection.ShowDialog();
imagePath.Text = imageFolderSelection.SelectedPath;
}
private void renderButton_Click(object sender, EventArgs e)
{
string imageSavePath = imagePath.Text;
string scene = sceneFile.Text;
try
{
if (FirstFrameTextbox.Text != "" && LastFrameTextBox.Text != "") // if the textboxes are filled in then assign them to a variable
{
firstFrame = Convert.ToInt32(FirstFrameTextbox.Text);
lastFrame = Convert.ToInt32(LastFrameTextBox.Text);
if (File.Exists(scene))
{
if (File.Exists(batchFile))
{
currentFrame = firstFrame;
progressMessage.Text = " Rendering Frame " + currentFrame + " of " + lastFrame + " from " + scene;
Render();
}
else
{
File.Create(batchFile); // if there is no batch file then we make one!
currentFrame = firstFrame;
progressMessage.Text = " Rendering Frame " + currentFrame + " of " + lastFrame + " from " + scene;
Render();
}
}
else // if there is not a scene file we let the user know that
{
MessageBox.Show("Please fill in image path, project path and scene file", "Cannot find file");
progressMessage.Text = " ERROR! SCENE FILE OR IMAGE PATH IS MISSING";
}
}
else
{
MessageBox.Show("The numbers entered into the first or last frame fields are invalid", "invalid frame range");
}
}
catch (Exception f)
{
MessageBox.Show(f.ToString() + " Most commonly errors result non numerical input in the frame entry fields", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private void ChangeRenderPath_Click(object sender, EventArgs e)
{
OpenFileDialog renderfinder = new OpenFileDialog();
renderfinder.Title = "Browse to your Render.exe file";
renderfinder.RestoreDirectory = true;
if (renderfinder.ShowDialog() == DialogResult.OK)
{
StreamWriter preferences = new StreamWriter(prefFile);
renderPathField.Text = renderfinder.FileName;
preferences.Write(renderPathField.Text);
preferences.Close();
}
}
public bool IsRendering(string processName)
{
foreach (Process renderProcess in Process.GetProcesses())
{
if (renderProcess.ProcessName.Contains(processName))
{
return true;
}
}
return false;
}
void Render()
{
while (currentFrame <= lastFrame)
{
bool rendering = IsRendering("cmd");
if (rendering == false)
{
StreamWriter renderBatch = new StreamWriter(batchFile);
renderBatch.Write('"' + renderPathField.Text + '"' + " -rd " + '"' + imagePath.Text + '"' + " -s " + currentFrame + " -e " + currentFrame + " " + '"' + sceneFile.Text + '"');
renderBatch.Close();
var renderProcess = new Process();
renderProcess.StartInfo = new ProcessStartInfo(batchFile);
//renderProcess.StartInfo.Arguments = '"' + renderPathField.Text + '"' + " -rd " + '"' + imagePath.Text + '"' + " -s " + currentFrame + " -e " + currentFrame + " " + '"' + sceneFile.Text + '"';
renderProcess.StartInfo.UseShellExecute = false;
//renderProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
renderProcess.Start();
if (renderProcess.HasExited == true && currentFrame < lastFrame)
{
ProgressBar1.Value = (currentFrame - 1) / lastFrame;
currentFrame++; //goes onto the next frame once it is done rendering this frame
}
}
}
}
private void Form1_FormClosing_1(object sender, FormClosingEventArgs e)
{
if (DialogResult.No == MessageBox.Show("If this program is not open it will not assign renders. Would you still like to close?", "You are about to stop rendering!", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation))
{
e.Cancel = true;
}
else
{
foreach (Process renderProcess in Process.GetProcesses())
{
if (renderProcess.ProcessName.Contains("cmd"))
{
renderProcess.Kill();
}
}
}
}
} // form closing brace
}
答案 0 :(得分:3)
UI更新需要在与主进程不同的线程上进行,否则它将等到整个进程完成后再显示更新的UI。
由于表单中有很多“进程”代码,因此没有简单的修复 - 您需要在另一个线程中启动处理并设置事件以将更新传递回UI。