В веб-приложении asp.net я хочу писать в файл. Эта функция сначала получит данные из базы данных, а затем запишет плоский файл.
Что я могу сделать, чтобы убедиться, что выполняется только одна запись, а когда запись происходит, другие потоки, которые, возможно, хотят записать в файл, этого не делают, поскольку запись была произведена.
Я хочу, чтобы эта запись была сделана ТОЛЬКО, если это не было сделано, скажем, за 15 минут.
Я знаю, что есть ключевое слово блокировки, поэтому мне следует заключить все в блокировку, а затем проверить, было ли она обновлена через 15 минут или более, или наоборот?
Обновлять
Рабочий процесс:
Поскольку это веб-приложение, несколько экземпляров будут людьми, просматривающими определенную веб-страницу. Я мог бы использовать сборку в системе кеширования, но если asp.net перерабатывает, восстановление кеша будет дорогостоящим, поэтому я просто хочу записать его в плоский файл. Другой вариант - просто создать службу Windows, но мне нужно больше работы по управлению.





Синхронизируйте свой код записи, чтобы заблокировать общий объект, чтобы только один поток попал внутрь блока. Остальные ждут выхода текущего.
lock(this)
{
// perform the write.
}
Обновление: я предполагал, что у вас есть общий объект. Если это разные процессы на одном компьютере, вам понадобится что-то вроде Named Mutex. Посмотрите здесь для примера
Я думаю, что это не сработает по причинам, которые я объяснил ниже.
не лучше ли заблокировать объектную переменную, а не весь экземпляр?
Я не уверен, что блокировка .NET применима к разным процессам. Более того, lock (this) будет исключать только другие потоки, которые запускают метод в том же экземпляре «this», поэтому другие потоки даже в том же процессе могут выполняться одновременно в разных экземплярах.
Предполагая, что все ваши процессы работают на одном компьютере, блокировка файлов должна сделать это.
Если вы работаете на разных машинах, ваш опыт может отличаться - win32 утверждает, что блокировка файлов работает по сети, но исторически сложилось так, что приложения, которые полагаются на нее (например, MSAccess), в любом случае имеют проблемы с повреждением файлов.
Вы правы, что для того, чтобы блокировка сработала, вам понадобятся все методы для использования одного и того же экземпляра this. Решением здесь может быть создание экземпляра фиктивного объекта статический, который обеспечит это.
// try enter will return false if another thread owns the lock
if (Monitor.TryEnter(lockObj))
{
try
{
// check last write time here, return if too soon; otherwise, write
}
finally
{
Monitor.Exit(lockobj);
}
}
это то же самое, что и lock (lockObj) {}.
Операции файлового ввода-вывода, которые записывают в файл, автоматически блокируют файл. Проверьте, заблокирован ли файл (попробовав запись) и не записывайте. Прежде чем выполнять какие-либо операции записи, проверьте отметку времени в файле и убедитесь, что она больше 15 минут.
afaik, вы не можете писать в файл, если он не заблокирован Windows / чем-то еще.
Теперь все, что вам осталось, это посмотреть, как сделать это с помощью msdn (извините, я не могу утруждать себя поиском всего этого, и я не очень хорошо помню классы C#). :)
Обратите внимание: мой ответ зависит от надежности временных меток - не всегда хорошее предположение. Вместо этого вы можете оставить файл открытым, чтобы в него не производилась запись в течение 15 минут после того, как какой-либо процесс завершит запись. :)
Используйте блокировки файловой системы
Как и другие предположения, блокировки .NET в этой ситуации будут иметь ограниченное применение. Вот код:
FileInfo fi = new FileInfo(path);
if (fi.Exists
&& (DateTime.UtcNow - fi.LastWriteTimeUtc < TimeSpan.FromMinutes(15)) {
// file is fresh
return;
}
FileStream fs;
try {
fs = new FileStream(
path, FileMode.Create, FileAccess.Write, FileShare.Read);
} catch (IOException) {
// file is locked
return;
}
using (fs) {
// write to file
}
Это будет работать через потоки процессов и.
Ребята, вам стоит подумать о Мьютекс. Он может синхронизировать несколько потоков и процессов.
Все ли записи происходят в одном экземпляре одного приложения? Или несколько экземпляров приложения будут пытаться писать одновременно, или разные приложения будут пытаться писать одновременно?