【问题标题】:How to do something while a process is running in Unity3d如何在 Unity3d 中运行进程时执行某些操作
【发布时间】:2016-04-22 08:33:21
【问题描述】:

我正在从 unity 运行一个进程,这需要一些时间(实际上可能需要 30 分钟),但是我希望 unity 运行它最多 5 分钟,如果没有输出,则返回。 我也想在这个等待 5 分钟的时间里展示这样的东西

有人知道怎么做吗?我尝试使用这行代码

    myProcess.WaitForExit(1000 * 60 * 5);

但是在它等待的时候我什么都做不了,我猜它阻止了我什么的,有人可以帮忙吗?

编辑:

   public void onClickFindSol(){
    paused=true;
    ReadRedFace();
    ReadGreenFace();
    ReadBlueFace();
    ReadYellowFace();
    ReadOrangeFace();
    ReadWhiteFace();
    if (File.Exists (path))
        File.Delete (path);
    System.IO.File.WriteAllText(path,InputToAlgo);      
    myProcess = new Process();
    myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    myProcess.StartInfo.CreateNoWindow = true;
    myProcess.StartInfo.UseShellExecute = false;
    myProcess.StartInfo.RedirectStandardOutput = true;
    myProcess.StartInfo.FileName = (System.Environment.CurrentDirectory )+Path.DirectorySeparatorChar+"rubik3Sticker.ida2";
    myProcess.EnableRaisingEvents = true;
    myProcess.StartInfo.WorkingDirectory = (System.Environment.CurrentDirectory )+Path.DirectorySeparatorChar;
    myProcess.StartInfo.Arguments = "corner.bin edge1.bin edge2.bin";
    myProcess.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
    {
        if (!String.IsNullOrEmpty(e.Data)){
            timer = 0f;
            StepsOfSolution++;
            print(e.Data);
            solution.output.Add(e.Data);
        }
    });
    myProcess.Start();
    myProcess.BeginOutputReadLine();
}
void Update(){
    if (myProcess != null){
        if(timer>fiveMinutes){
            myProcess.Kill();
            myProcess.Close();
            badExit=true;
            myProcess=null;
            return;
        }
        timer += Time.deltaTime;
        if (!myProcess.HasExited){
            RubikScene.PleaseWait.SetActive(true);
        }
        else{
            if(badExit){
                RubikScene.PleaseWait.SetActive(false);
                RubikScene.TooLong.SetActive(true);
                print("TimeOut!");
            }else{
                paused=false;
                Application.LoadLevel("solution");
            }
        }
    }
}

【问题讨论】:

  • 每隔 X 秒做一次定时器检查输出,如果定时器不超过 5 分钟,则停止进程,无需阻塞任何东西
  • @user2320445 WaitForExit 阻止一切。

标签: c# unity3d process


【解决方案1】:

不要使用myProcess.WaitForExit()。它将阻塞直到它返回。使用myProcess.Start(),然后在您的更新函数中,在if !myProcess.HasExited 中运行您的动画。您的代码不完整,因此我将提供不完整的解决方案,但这应该可以。

void Start()
{
 timer = 0;//Reset Timer
 myProcess.Start();
}

在更新函数中检查进程是否完成

float timer = 0f;
float fiveMinutes = 300; //300 seconds = 5minutes
bool badExit = false;

void Update()
{
 if (myProcess != null)
 {
    //Check if Time has reached
    if(timer>fiveMinutes){
        myProcess.Kill();
        myProcess.Close();
        badExit = true;
        return;
    }
    timer += Time.deltaTime;

   if (!myProcess.HasExited)
   {
    //Do Your Animation Stuff Here
   }else{
      //Check if this was bad or good exit
      if(badExit){
        //Bad
       }else{
        //Good
        }
    }
 }
}

然后在您从进程接收/读取的回调函数中的其他位置,如果读取的字节为 >0,则始终将计时器重置为 0。这样计时器只会在 5 分钟 内没有收到任何东西时计数到 5 分钟

myProcess.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
// Prepend line numbers to each line of the output.
if (!String.IsNullOrEmpty(e.Data))
 {
    timer = 0f; //Reset Process Timer
    lineCount++;
    output.Append("\n[" + lineCount + "]: " + e.Data);
 }
});

OR 与 回调 函数

private static void SortOutputHandler(object sendingProcess, 
            DataReceivedEventArgs outLine)
 {
  // Collect the sort command output.
  if (!String.IsNullOrEmpty(outLine.Data))
   {
      timer = 0f; //Reset Process Timer
      numOutputLines++;

      // Add the text to the collected output.
      sortOutput.Append(Environment.NewLine + 
      "[" + numOutputLines.ToString() + "] - " + outLine.Data);
   }
 }

【讨论】:

  • 如果设置timer = Time.time然后使用timer < Time.time+fiveMinutes而不是timer = 0会更简单
  • 我避免使用Time.time。这是游戏开始以来的时间。枪跑得越多,这个数字就越高,这个数字就越大。在某些时候,你会得到一个非常大的数字,比如 93848589323 +fiveMinutes 并且没有人知道它什么时候重置。 Time.deltaTime 返回不需要大数字操作的小数字,它还取决于帧速率,这意味着它将在每个设备上以相同的方式运行。
  • @msLangdon95 在if(timer>fiveMinutes){ 内。如果这是真的,那么你知道你在 5 秒内没有收到任何东西。在那里,进程被杀死并关闭,您可以在那里添加其他将运行的代码。 if 语句中的任何代码都意味着出现问题。我还修改了答案,以便您可以在 Update 函数中检查错误退出和良好退出。看看我在哪里放if(badExit){
  • 我爱你,谢谢@Programmer
  • if(timer>fiveMinutes){ myProcess.Kill(); myProcess.Close(); badExit = true; return; } 替换为 if(timer>fiveMinutes){ myProcess.Kill(); myProcess.Close(); badExit = true; myProcess = null; return; } 让我知道这是否解决了您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
相关资源
最近更新 更多