.Net Runtime Ошибка остановки службы;Необработанное IOException - PullRequest
1 голос
/ 05 мая 2011

Я был назначен ответственным за обновление службы, которая читает текстовый файл и создает 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) в 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 ]

2 голосов
/ 05 мая 2011

Вы пытаетесь использовать класс Console в службе, с которой не связано окно консоли.Вы должны использовать некоторую альтернативную форму регистрации, которая не предполагает наличие консольного окна.log4net, в качестве одного примера, позволяет настроить несколько «добавителей», таких как консоль, файл и приложение журнала событий, для одновременного использования (и будет просто проигнорировано, если они не подходят).* ИЗМЕНИТЬ, чтобы уточнить:

Вы можете создать консольное окно вручную с помощью вызова AllocConsole P / Invoke, если вам это абсолютно необходимо.По умолчанию служба не взаимодействует с вашим рабочим столом, поэтому создание окна консоли было бы плохой идеей.Чтобы это работало, вам необходимо настроить службу с включенной настройкой «Разрешить службе взаимодействовать с рабочим столом» .Это имеет значение для безопасности, особенно для компьютеров с несколькими пользователями, поэтому я бы посоветовал против этого.

0 голосов
/ 05 мая 2011

Также вы должны убедиться, что ваша подпрограмма m_log правильно обрабатывает ошибки, так как это также может быть причиной.

0 голосов
/ 05 мая 2011

Похоже, что здесь происходит ошибка до того, как вы попытаетесь поймать. Учитывая, что вы должны видеть конкретное сообщение, выводимое вашей регистрацией (я предполагаю, что оно отправляется в журнал событий). Я не вижу сообщения, похожего на то, что есть в вашем журнале. Возможно, вы захотите иметь обработчик исключений домена приложения, чтобы перехватывать любые исключения и регистрировать их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...