2015-01-21 51 views
0

我的代码:的AutoResetEvent不工作

static AutoResetEvent wait_till_finish = new AutoResetEvent(false); 

...if (File.Exists("try.exe")) 
       { 
        Thread quartus_thread = new Thread(() => qar_function(@"\quartus"); 
        quartus_thread.Start(); 
        wait_till_finish.WaitOne(); 
    // ONLY after command mode action was finished, and AutoResetEvent is set, lookfor some file in folder 
        if (File.Exists("def")) {//do something} 
       } 

,稍后:

public void qar_function(string abc) 
    { //does something... 
      ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/k " + String.Join(" ", args)); 
      procStartInfo.RedirectStandardOutput = true; 
      procStartInfo.RedirectStandardError = true; 
      procStartInfo.UseShellExecute = false; 
      procStartInfo.CreateNoWindow = false; 
      Process proc = new Process(); 
      proc.StartInfo = procStartInfo; 
      proc.Start(); 
      // ***** now set AutoResetEvent: 
      wait_till_finish.set(); 

我的问题是:

我`wait_till_finish.WaitOne()在一种方法中,并且在我调用Qar_Function方法之后它处于等待状态,所以首先我要调用方法,然后我想等待方法执行并完成,然后在qar_function方法内设置AutoR ESET。

它不工作。

我正在使用调试器,它并没有在WaitOne等待,它只是继续移动到下一行。

我在做什么错? Thx。

+0

您的意思是启动一个进程或等待进程结束?在设置句柄 – 2015-01-21 08:40:20

+0

之前,您可能需要调用'proc.WaitForExit()'来完成我的过程,然后再找到该文件。我现在认为它会在启动时发生,而不是在完成时发生......我该如何改变它? – 2015-01-21 08:44:40

+0

您必须在代码的开头某处调用Reset()方法,或者,使用true初始化您的AutoResetEvent:wait_till_finish = new AutoResetEvent(true); – Younes 2015-01-21 08:45:19

回答

3

有两种方法可以等待进程退出。一个是同步的,另一个是异步的。

如果您更喜欢同步使用Process.WaitForExit否则使用Process.Exited事件。

所以在您致电process.Start后,您可以致电process.WaitForExit等待它完成。

对我来说,它看起来像你只是简单地创建新的线程,并启动进程并计划等待它 - 同时另一个线程正在等待这个线程。所有这些看起来没有效率的资源使用。您可以避免创建新线程,只需内联进程创建并在调用线程本身中等待它。在这种情况下,你甚至不需要AutoResetEvent

在这一点上你的代码变成:

if (File.Exists("try.exe")) 
{ 
    ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/k " + String.Join(" ", args)); 
    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.RedirectStandardError = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = false; 
    Process proc = new Process(); 
    proc.StartInfo = procStartInfo; 
    proc.Start(); 
    proc.WaitForExit(); 

    //At this point the process you started is done. 
    if (File.Exists("def")) 
    { 
     //do something 
    } 
} 
+0

当然,一个'Process'是一个等待句柄,所以你可以使用像这样的东西http://stackoverflow.com/questions/13741694/construct-task-from-waithandle-wait来获得一个'Task' out它。 – Luaan 2015-01-21 09:02:21

+0

@Luaan Yep,从中获取一个'Task'听起来像是一个好主意,但相关答案是使用ThreadPool.RegisterWaitForSingleObject重新发明轮子,通过订阅'Exited'事件和'TaskCompletionSource', 。 – 2015-01-21 09:07:30

+0

是的,那是另一种选择。我个人试图在不需要事件时避免事件(并且'Exited'事件无论如何都使用相同的等待处理)。 – Luaan 2015-01-21 09:14:27