流程退出但实际上并未完成

时间:2013-10-25 22:13:40

标签: c#

我试图用简单的代码调用应用程序,如

public void Run(string command)
{
    Process proc = new Process();
    proc.StartInfo.FileName = "acvTemp.exe";
    proc.StartInfo.Arguments = command;             

    proc.Start();

    proc.WaitForExit();
}

我正在启动的fileName进程实际上会生成一个新窗口。它正在推出一些命令,使其无法退出。我是

command = acvtest.exe /launch /wait /log:<temp.log>

所以acvtest.exe开始在机器上运行,实际上仍在运行,所以我可以运行其他命令,如

acvtest.exe /getid:<name>

我将手动使用该应用程序。

acvtest.exe /launch /wait /log:<temp.log>
acvtest.exe /getid:<name>

注意实际/启动进程返回shell命令提示符,因为使用/ launch打开一个新命令窗口并且/ getid的输出实际写入日志。

我的问题是当第一个/ launch或/ getid命令运行时,即使在日志上释放句柄之前,waitforexit()似乎也在退出。 (可能在某些孩子出手之前?)

即以下命令失败,直到我进行一些睡眠或等待。即使是waitforexit()

 Run("/launch /wait /log:<temp.log>");
 Run("/getid:<name>");
 Run("shutdown");

 //Needs some sleep or wait here

 using (StreamReader reader = new StreamReader("temp.log"))
 {
     Console.WriteLine(reader.ReadToEnd());
 }

在上述两个部分之间没有任何睡眠或等待,访问日志失败,错误是它已被另一个进程使用。看起来应用程序甚至在实际完成其进程之前就已退出。这是应用程序的问题吗?我可以做些什么来解决它?

我怀疑我可能需要一些不同的Run()代码,因为启动了一个新的shell。

[更新]

问题不仅在于日志文件。当我在运行Run(“/ getid:”)上说大约有100,000个文件名时,其中许多都因“资源不可用”错误而失败,这就是为什么我认为应用程序可能在它发布资源之前就已经退出了 谢谢你的期待。

3 个答案:

答案 0 :(得分:0)

  

这是应用程序的问题吗?我能做的任何工作   在它周围?

我想说应用程序可能没有任何问题。很可能该文件根本没有被操作系统本身完全释放。

常见的解决方法是尝试在Try / Catch块中读取文件,并将其包含在延迟的while循环中,或者从Timer调用该代码。

答案 1 :(得分:0)

提出了文件锁定问题的一种解决方案here。然后,您可以提取感兴趣的过程的PID。

然后,如果日志文件保持打开状态,直到进程退出,那么就有“信号量”。

答案 2 :(得分:0)

我想您可以尝试使用以下代码以只读方式打开文件

FileStream fs = File.Open("temp.log", FileMode.Open, FileAccess.Read);

或者你使用像这样的代码:

try
{
    // some code here ...

    // Try to access the file within 1000 (or whatever is specified) ms.
    FileAccessHelper.WaitForFileAccessibility("test.log", 1000);

    // and here ...
}
catch (FileAccessHelperException e)
{
    // your error handling here...
    Console.WriteLine("Unable to open the file within 1000ms");
}

FileAccessHelper类如下所示:

namespace CodingFun
{
    using System;
    using System.IO;
    using System.Threading;

    /// <summary>
    /// Represents our FileAccessHelper class.
    /// </summary>
    public static class FileAccessHelper
    {
        /// <summary>
        /// Blocks until the specified file can be accessed or a timeout occurs.
        /// </summary>
        /// <param name="filename">The file which shall be accessed.</param>
        /// <param name="timeout">The timeout in milliseconds.</param>
        /// <param name="accessMode">Specifies the file access mode, default is read only.</param>
        public static void WaitForFileAccessibility(string filename, int timeout, FileAccess accessMode = FileAccess.Read)
        {
            int tries = 0;
            bool readDone = false;

            do
            {
                try
                {
                    // Try to open the file as read only.
                    FileStream fs = File.Open(filename, FileMode.Open, accessMode);

                    // Close it if it worked and...
                    fs.Close();

                    // ... set a flag so that we know we have successfully opened the file.
                    readDone = true;
                }
                catch (Exception e)
                {
                    // increase the counter and...
                    tries++;

                    // ... check if a timeout occured.
                    if ((100 * tries) >= timeout)
                    {
                        throw new FileAccessHelperException(string.Format("Unable to access the file {0} within the specified timeout of {1}ms", filename, timeout), e);
                    }
                    else
                    {
                        // If not just sleep 100 ms.
                        Thread.Sleep(100);
                    }
                }
            }
            while (!readDone);
        }
    }
}

FileAccessHelperException类如下所示:

namespace CodingFun
{
    using System;
    using System.Runtime.Serialization;
    using System.Security;

    /// <summary>
    /// Represents the FileAccessHelperException class.
    /// </summary>
    public class FileAccessHelperException : Exception
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FileAccessHelperException"/> class.
        /// </summary>
        public FileAccessHelperException()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileAccessHelperException"/> class.
        /// </summary>
        /// <param name="message">The message that describes the error.</param>
        public FileAccessHelperException(string message)
            : base(message)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileAccessHelperException"/>
        /// class with a specified error message and a reference to the inner
        /// exception that is the cause of this exception.
        /// </summary>
        /// <param name="message">The error message that explains the reason for the exception.</param>
        /// <param name="innerException">
        /// The exception that is the cause of the current exception, or a null reference
        /// if no inner exception is specified.
        /// </param>
        public FileAccessHelperException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileAccessHelperException"/> class with serialized data.
        /// </summary>
        /// <param name="info">
        /// The System.Runtime.Serialization.SerializationInfo that holds the serialized
        /// object data about the exception being thrown.
        /// </param>
        /// <param name="context">
        /// The System.Runtime.Serialization.StreamingContext that contains contextual
        /// information about the source or destination.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// The info parameter is null.
        /// </exception>
        /// <exception cref="System.Runtime.Serialization.SerializationException">
        /// The class name is null or System.Exception.HResult is zero (0).
        /// </exception>
        [SecuritySafeCritical]
        protected FileAccessHelperException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }
}

我希望有所帮助; - )