IIS блокирует файл, созданный XMLWriter

Я написал .Net Web API, который принимает входные данные, анализирует их, а затем сохраняет файл XML в сетевой папке, связанной с нашим сервером. Я также создал службу Windows, которая сканирует сетевой ресурс на наличие новых файлов для обработки нашей бизнес-логики.

Это работает почти в 100% случаев, но очень редко (1 из 20 000 раз) IIS6 удерживает блокировку файла, который он создает, и не снимается до тех пор, пока IIS не будет перезапущен. Заблокированные файлы всегда имеют размер 0 байт.

В настоящее время у меня есть файл, который был заблокирован почти 20 часов! Вот код, который создает файл:

    Try
        '-- Make sure the file doesn't already exist
        TempFileName = strFullFileName
        i = 1

        While IO.File.Exists(TempFileName)
            TempFileName = strFullFileName.Replace(".xml", "_" & i & ".xml")

            i += 1
        End While

        strFullFileName = TempFileName

        '-- Deserialise the message into a file
        drSerializer = New XmlSerializer(DetailsOfMsg.GetType)
        FS = New FileStream(strFullFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None)
        XW = XmlWriter.Create(FS)
        drSerializer.Serialize(XW, DetailsOfMsg)

    Finally
        Try : XW.Flush() : Catch : End Try
        Try : FS.Close() : Catch : End Try
        Try : XW.Close() : Catch : End Try
        FS = Nothing
        XW = Nothing
    End Try

Почему IIS все еще держит блокировку?


person aaroncatlin    schedule 22.01.2015    source источник


Ответы (3)


Вы пытались обернуть код в блоки «Использование»? Это гарантирует, что типы FileStream и XmlWriter будут удалены после окончания области действия блока.

person Jebahar Deva Dhason D R    schedule 27.01.2015
comment
Спасибо за ответ. Я добавил блоки «Использование» в свой код, но он не будет использоваться в нашей производственной среде в течение нескольких дней, поэтому я не смогу подтвердить, что он решает проблему сразу. - person aaroncatlin; 29.01.2015
comment
Ну, очевидно, я протестировал код, прежде чем он пойдет в производство. Если бы вы читали мой пост, вы бы знали, что проблема возникает только в рабочей среде и очень редко, поэтому я не могу воспроизвести проблему в нашей среде Stage. Поэтому единственный способ узнать, что проблема решена, — это отслеживать ее в нашей производственной среде. - person aaroncatlin; 02.02.2015
comment
Похоже, это решило проблему, по крайней мере, для сегодняшнего трафика. Я буду продолжать следить, но отметил это как ответ. Спасибо. - person aaroncatlin; 03.02.2015
comment
К сожалению, проблема все еще иногда возникает. Я собираюсь приписать это почти устаревшему Windows Server 2003 и IIS 6, работающим на VMWare. В этом году мы собираемся обновить нашу ОС, так что, надеюсь, это решит проблему навсегда. - person aaroncatlin; 28.02.2015

Я думаю, вам нужно разделить этот процесс. Сначала создайте файл, скажем, в папке X. После создания переместите этот файл из папки X в общую папку, так как с этим сетевым ресурсом связан наблюдатель. Кроме того, как только файл будет найден, выберите его и перейдите в рабочую папку, а затем запустите свой бизнес-процесс с этим файлом. 0 байт может быть индикатором взаимоблокировки записи и просмотра.

person Amit    schedule 02.02.2015
comment
Хорошее предложение, спасибо. Я попробую это, если использование блоков не имеет никакого эффекта. - person aaroncatlin; 02.02.2015

Я вижу, что вы создали FileStream экземпляр с FileShare = none, тогда как в вашем требовании говорится, что вам нужно одновременно читать и писать в общем месте.

Правильный код будет

FS = New FileStream(strFullFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)

FileShare — константа, определяющая, как файл будет совместно использоваться процессами.

Для получения дополнительной информации см. это - https://msdn.microsoft.com/en-us/library/5h0z48dh(v=vs.110).aspx

ИЗМЕНИТЬ

Из комментария я обнаружил, что вам нужно применить блокировку для операции Read, и ошибка, которую вы получаете (не так часто), может быть связана с блокировкой записи. Чтобы избежать этого, вы можете использовать следующее.

FS = New FileStream(strFullFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Write)

FileShare.Write - Разрешает последующее открытие файла для записи. Если этот флаг не указан, любой запрос на открытие файла для записи (этим процессом или другим процессом) не будет выполнен до тех пор, пока файл не будет закрыт. Однако даже если этот флаг указан, для доступа к файлу могут потребоваться дополнительные разрешения.

person Arindam Nayak    schedule 30.01.2015
comment
Я не хочу одновременно читать и писать в файл. Файл должен оставаться заблокированным до тех пор, пока он не будет записан, и служба Windows будет ждать, пока он больше не будет заблокирован, чтобы обработать его. В противном случае важная информация может не записаться в файл при его обработке. - person aaroncatlin; 30.01.2015
comment
При этом он не будет заблокирован для операций чтения, во время записи вы можете искать другие значения для FileShare, есть еще одно значение Read. - person Arindam Nayak; 30.01.2015
comment
Я хочу, чтобы файл был заблокирован до тех пор, пока он не будет полностью записан, иначе служба Windows переместит его в папку Failed. Я не уверен, что вы поняли мой вопрос. - person aaroncatlin; 30.01.2015