Проблема, пишущая в единственный файл в веб-сервисе в.NET

Вместо того, чтобы отбрасывать таблицу резервного копирования, просто переименуйте ее ...

BEGIN TRANSACTION;
CREATE TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
ALTER TABLE t1_backup RENAME TO t1;
COMMIT;
6
задан KyleMit 21 August 2014 в 15:06
поделиться

11 ответов

Блокировка, вероятно, перестала работать, потому что Ваш веб-сервис выполняется больше чем одним рабочим процессом. Вы могли защитить доступ с именованным взаимным исключением, которое совместно используется через процессы, в отличие от блокировок, при помощи которых Вы добираетесь lock(someobject) {...}:

Mutex lock = new Mutex("mymutex", false);

lock.WaitOne();

// access file

lock.ReleaseMutex();
10
ответ дан 9 December 2019 в 22:42
поделиться

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

Я думаю, что пошел бы для решения, которое Вы предлагаете сами, Pradeep, создаете отдельный объект, который делает все записи к файлу журнала. В том объекте у меня была бы Очередь, в которую записаны все данные быть зарегистрированными. У меня был бы отдельный поток, читающий из этой очереди и пишущий в файл журнала. В объединенной потоком среде хостинга как IIS не кажется слишком хорошим создать другой поток, но это - только один... Примите во внимание, что очередь в оперативной памяти не переживет сброс IIS; Вы могли бы потерять некоторые записи, которые "в полете", когда процесс IIS понижается.

Другие альтернативы, конечно, включают использование отдельного процесса (такой как услуга) для записи в файл, но это имеет дополнительное развертывание наверху и затраты IPC. Если это не работает на Вас, пойдите с одиночным элементом.

1
ответ дан 9 December 2019 в 22:42
поделиться

Вы могли продвинуть результаты на Очередь MSMQ и сделать, окна обслуживают, собирают объекты очереди и регистрируют их. Это немного тяжело, но это должно работать.

0
ответ дан 9 December 2019 в 22:42
поделиться

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

0
ответ дан 9 December 2019 в 22:42
поделиться

Joel и charles. Это было быстро!:)

Joel: при высказывании "строки очереди", Вы означаете создавать отдельный поток, который работает в цикле, чтобы продолжать проверять очередь, а также писать в файл, когда это не заблокировано?

Charles: Я знаю о MSMQ и сервисной комбинации окон, но как я сказал, что у меня нет выбора кроме записи в файл из веб-сервиса :)

спасибо pradeep_tp

0
ответ дан 9 December 2019 в 22:42
поделиться

Для знания, что я пытаюсь сделать в своем коде следующее является singletone классом, который я реализовал в C#

общедоступный запечатанный класс FileWriteTest {

private static volatile FileWriteTest instance;

private static object syncRoot = new Object();

private static Queue logMessages = new Queue();

private static ErrorLogger oNetLogger = new ErrorLogger();

private FileWriteTest() { }

public static FileWriteTest Instance
{
    get
    {
        if (instance == null)
        {
            lock (syncRoot)
            {
                if (instance == null)
                {
                    instance = new FileWriteTest();
                    Thread MyThread = new Thread(new ThreadStart(StartCollectingLogs));
                    MyThread.Start();

                }
            }
        }

        return instance;
    }
}

private static void StartCollectingLogs()
{

    //Infinite loop
    while (true)
    {
        cdoLogMessage objMessage = new cdoLogMessage();
        if (logMessages.Count != 0)
        {
            objMessage = (cdoLogMessage)logMessages.Dequeue();
            oNetLogger.WriteLog(objMessage.LogText, objMessage.SeverityLevel);

        }
    }
}

public void WriteLog(string logText, SeverityLevel errorSeverity)
{
    cdoLogMessage objMessage = new cdoLogMessage();
    objMessage.LogText = logText;
    objMessage.SeverityLevel = errorSeverity;
    logMessages.Enqueue(objMessage);

}

}

Когда я работаю, этот код в режиме отладки (моделирует всего один пользовательский доступ), я получаю ошибку "переполнение стека" в строке, где очередь исключается из очереди.

Примечание: В вышеупомянутом коде ErrorLogger является классом, который имеет код для записи в Файл. objMessage является классом объекта для переноса сообщения журнала.

0
ответ дан 9 December 2019 в 22:42
поделиться

Проблема со всем приближенным, который попробовали до сих пор, состоит в том, что несколько потоков могут ввести код. Это - несколько попыток потоков получить и использовать обработчик файлов - следовательно ошибки - Вам нужен единственный поток за пределами рабочих потоков, чтобы сделать работу - с единственным дескриптором файла, сохраненным открытым.

Вероятно, самая легкая вещь сделать состояла бы в том, чтобы создать поток во время приложения, запускаются в Global.asax и имеют, которые слушают синхронизируемую очередь в оперативной памяти (Система. Наборы. Дженерики. Очередь). Имейте поток, открывают и владеют временем жизни дескриптора файла, только тот поток может записать в файл.

Клиентские запросы в ASP заблокируют очередь на мгновение, продвинуть новое сообщение входа на очередь, затем разблокировать.

Поток регистратора будет опрашивать очередь периодически относительно новых сообщений - когда сообщения прибудут в очередь, поток считает и отправит данные в файлу.

0
ответ дан 9 December 2019 в 22:42
поделиться

С другой стороны, Вы могли бы хотеть сделать регистрацию ошибок в базу данных (при использовании одного),

0
ответ дан 9 December 2019 в 22:42
поделиться

Koth,

Я реализовал Взаимоисключающую блокировку, которая удалила ошибку "переполнения стека". Я все же должен сделать загрузку, тестирующую, прежде чем я смогу завершить, хорошо работает ли она во всех случаях.

Я читал о Взаимном исключении objets в одном из веб-сайтов, который говорит, что Взаимное исключение влияет на производительность. Я хочу знать одну вещь с проведением блокировки через Взаимное исключение.

Предположим Пользователь, которого Process1 пишет в файл и в то же время Пользователю, которого Process2 пытается записать в тот же файл. Так как Process1 поместил блокировку в блок кода, будет Process2 продолжать пробовать или просто умирать после первого attempet iteself.?

спасибо pradeep_tp

0
ответ дан 9 December 2019 в 22:42
поделиться

Это будет ожидать, пока взаимное исключение не выпущено....

0
ответ дан 9 December 2019 в 22:42
поделиться

Joel: при высказывании "строки очереди", Вы означаете создавать отдельный поток, который работает в цикле, чтобы продолжать проверять очередь, а также писать в файл, когда это не заблокировано?

Да, это в основном, что я думал. Имейте другой поток, который имеет некоторое время цикл, пока это не может получить доступ к файлу и сохранить, затем закончиться.

Но необходимо было бы сделать это способом, где первый поток, который начнет смотреть, получает доступ сначала. Который является, почему я говорю очередь.

0
ответ дан 9 December 2019 в 22:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: