Используйте FileShare.ReadWrite с HttpPostedFile в ASP.NET MVC - PullRequest
4 голосов
/ 25 мая 2019

Я использую приведенный ниже код, чтобы сохранить опубликованный файл на сервере, но этот файл постоянно читается, и мне нужно использовать FileShare.ReadWrite, чтобы не получить заблокированную ошибку.

 httpRequest.Files[0].SaveAs(filePath);

Ниже мой метод чтения, как мне добиться этого с помощью файла HttpPosted - это правильный путь с наилучшей производительностью.

using (var fileStream = new FileStream(
                   fileLocation,
                   FileMode.Open,
                   FileAccess.Read,
                   FileShare.ReadWrite))
                {
                    using (var streamReader = new StreamReader(fileStream))
                    {
                        xDocument = XDocument.Parse(streamReader.ReadToEnd());
                    }
                }

Это мой лучший вариант?

 using (var memoryStream = new MemoryStream())
                {
                    httpRequest.Files[0].InputStream.CopyTo(memoryStream);
                    var bytes = memoryStream.ToArray();

                    using (var fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
                    {
                        fs.Write(bytes, 0, bytes.Length);
                    }
                }

1 Ответ

2 голосов
/ 03 июня 2019

Proplem:

  • Требуется блокировка «Запись: один раз, чтение: много» * ​​1004 *

Допущения:

  • Файл небольшой(среднее число операций записи составляет 5000 мс)
  • Нет других операций записи или чтения (Только одна программа с 2 функциями)
  • Вы читаете файл намного больше, чем пишете в него

Решение


    using System;
    using System.IO;
    using System.Threading;
    using System.Web.Mvc;

    namespace stackoverflow_56307594.Controllers
    {

        public class HomeController : Controller
        {

            public ActionResult A()
            {
                readFile();
                return View();
            }

            public ActionResult B()
            {
                writeFile();
                return View();
            }


            private static object writeLock = new Object();

            private void readFile()
            {
                while (!Monitor.TryEnter(writeLock, 5000)) ; //wait 5000 ms for the writeLock (serializing access)
                using (var stream = new FileStream("filePath", FileMode.Open, FileAccess.Read, FileShare.Read))
                using (var reader = new StreamReader(stream))
                {
                    // active read
                    // xDocument = XDocument.Parse(streamReader.ReadToEnd());

                }
            }
            private void writeFile()
            {
                lock (writeLock)
                {
                    FileStream stream = null;
                    while (stream == null) //wait for the active read
                    {
                        try
                        {
                            stream = new FileStream("filePath", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                        }
                        catch (IOException)
                        {
                        // will fail if active read becase FileShare.None   while (stream == null) will  wait
                    }
                }
                    Request.Files[0].InputStream.CopyTo(stream);
                }// unlock
            }

        }
    }

Примечание:

  1. Я не тестировал нагрузку или просто тестировал решение на веб-сервере
  2. Я только тестировал его набумага ?

enter image description here

Refs:

блокировка - как долго будет ждать блокировка C #, и что есликод вылетает во время блокировки?- Переполнение стека

c # - Удаление используемых файлов - Переполнение стека

многопоточность - Есть ли способ определить, заблокирован ли объект?- Переполнение стека

Реализация Singleton в C # |Документы Microsoft

c # - Использование одной и той же блокировки для нескольких методов - Переполнение стека

c # - Однократная запись, Блокировка многократного чтения - СтекПереполнение

c # блокировка записи один раз прочитал много - Поиск Google

FileShare Enum (System.IO) |Документы Microsoft

...