.Net运行时错误停止服务;未处理的IOException

时间:2011-05-05 17:52:37

标签: c# .net windows-services

我负责更新读取文本文件的服务,并从文本文件的各个部分创建pdf文件并通过电子邮件发送出pdf文件。我最近对该服务进行了一些更改,并使用了.Net 4.0 Framework。在服务器上进行更新时,在我移动文件并成功启动服务之前安装了4.0 Framework - 它之前使用的是2.0。该服务一直运行,直到它到达尝试使用pdf文件清理目录的代码。该服务在代码尝试删除“正由另一个进程使用”的pdf文件时停止。代码查找此异常,并且应该等待大约30秒并再次尝试删除。在本地,我通过测试线束运行此服务,它循环直到文件可用于删除(平均需要大约5分钟),但在服务器上,服务停止,并在应用程序事件日志中找到未处理的IOException。我不明白为什么它会在本地继续处理但不在服务器上处理。非常感谢任何想法或其他信息。

以下是事件日志中的错误:

由于未处理的异常,该流程已终止。

  

异常信息:System.IO.IOException   堆:      在System.IO .__ Error.WinIOError(Int32,System.String)      at System.Console.GetBufferInfo(Boolean,Boolean ByRef)      at processorName.FileProcessingThread.CleanUpDirectory(System.Object)      在System.Threading.ThreadHelper.ThreadStart_Context(System.Object)      在System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object,Boolean)      在System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object)      在System.Threading.ThreadHelper.ThreadStart(System.Object)

此错误也会出现在事件日志中:

  

EventType clr20r3,P1 myServiceName.exe,P2 1.0.1.0,P3 4db6e85d,P4 mscorlib,P5 4.0.0.0,P6 4d53693b,P7 3dab,P8 23b,P9 system.io.ioexception,P10 NIL。

这是应该处理异常的代码,等待并重试删除文件。

while (!isDone)
{
    bool myRetVal = true;
    string myErrorMsg = String.Empty;
    string myFile = String.Empty;
    //give it time to finish processing
    Thread.Sleep(30 * 1000);
    //
    //delete Files in folder
    foreach (string file in Directory.GetFiles(myDirectory, "*.PDF"))
    {  //delete all the *.PDF files
        try
        {
            File.Delete(file);
        }
        catch (Exception ex)
        {
            myErrorMsg = "...\r\n" + ex.Message;
            m_Log.Writeline("Unable to delete "+ file + ". MESSAGE:"+ myErrorMsg,3);
            myFile = file;
            myRetVal = false;
        }
    }
    //
    //now move the in-progress File to the processed directory
    if (myRetVal)
    {
        foreach (string file in Directory.GetFiles(myDirectory, "*.InProgress"))
        {
            try
            {
                if (File.Exists(m_ConfigFile.ProcessedFolderName + Path.GetFileNameWithoutExtension(file) + ".done"))
                {
                    File.Delete(file);
                }
                else
                {
                    File.Move(file, m_ConfigFile.ProcessedFolderName + Path.GetFileNameWithoutExtension(file) + ".done");
                }
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("file already exists"))
                {

                }
                else
                {
                    myErrorMsg = "...\r\n" + ex.Message;
                    myFile = file;
                    myRetVal = false;
                }
            }
        }
    }
    //
    //if empty, delete the SendMailFolder subfolder
    if (myRetVal)
    {
        try
        {
            if (Directory.GetFiles(myDirectory, "*.*").Length == 0) Directory.Delete(myDirectory);
        }
        catch (Exception ex)
        {
            myErrorMsg = "...\r\n" + ex.Message;
            myFile = myDirectory;
            myRetVal = false;
        }
    }

    if (Console.CursorLeft > 0) Console.WriteLine("\r\n");

    if (myRetVal)
    {
        Console.WriteLine(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder...Done");
        isDone = true;
    }
    else
    {
        if (myErrorMsg.Contains("is being used by another process."))
        {
            myErrorMsg = " is still in use.";
            Console.WriteLine(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder..." + Path.GetFileName(myFile) + myErrorMsg);
        }
        else
        {
            Console.WriteLine(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder..." + Path.GetFileName(myFile) + myErrorMsg);
            m_Log.Writeline(DateTime.Now.ToLocalTime() + " CleanUp SendMailFolder..." + Path.GetFileName(myFile) + myErrorMsg, 3);
            isDone = true;
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您正在尝试在服务中使用Console类,该服务没有与之关联的控制台窗口。您应该使用一种不假设有控制台窗口的替代形式的日志记录。作为一个示例,log4net允许您配置多个“appender”,例如控制台,文件和事件日志追加器,以便同时使用(如果它们不合适,将会被忽略)。

编辑澄清:

如果您确实需要,可以使用AllocConsole P / Invoke调用手动创建控制台窗口。默认情况下,服务不会与您的桌面交互,因此创建控制台窗口是个坏主意。为此,您需要使用“允许服务与桌面交互”设置来配置服务。这具有安全隐患,特别是对于拥有多个用户的计算机,所以我建议不要这样做。

答案 1 :(得分:0)

看起来你的尝试捕获之前发生了错误。鉴于您应该看到日志记录输出的特定消息(我假设它转到事件日志)。我没有看到类似于您日志中的消息的消息。您可能希望有一个应用程序域异常处理程序来捕获任何异常并记录它们。

答案 2 :(得分:0)

此外,您应该确保您的m_log例程具有正确的错误处理,因为这也可能是罪魁祸首。