2013-10-23 2 views
0

애니메이션을 렌더링하기 위해 프로세스를 시작해야하는 코드가 있습니다. 그것은 훌륭하게 작동하고 프로세스와 모든 것을 시작하지만 프로세스가 실행되는 동안 내 프로그램이 응답하지 않는다고 말하며 진행 상황을 전혀 업데이트하지 못하도록 고정시킵니다.프로세스가 시작되는 동안 왜 지연되고 정지됩니까?

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 
} 

답변

3

UI 업데이트가 아닌 다른 스레드에서 발생해야합니다 여기

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 
      } 
     } 
    } 
} 

그것은에있는 전체 코드입니다 : 여기

는 문제가 발생한다 코드입니다 기본 프로세스가 아니라면 업데이트 된 UI를 표시하기 전에 전체 프로세스가 완료 될 때까지 대기합니다.

양식 내에 많은 "프로세스"코드가 있으므로 간단한 수정이 필요하지 않습니다. 다른 스레드에서 처리를 시작하고 이벤트를 설정하여 UI에 다시 업데이트를 전달해야합니다.

+0

정말 고마워요! 훌륭하게 작동합니다. 이 스레드를보고 솔루션에 대해 궁금한 사람은이 포럼 스레드에서 찾았습니다. http://stackoverflow.com/questions/363377/how-do-i-run-a-simple-bit-of-code-in-a-new-thread – mberna

관련 문제