evgen_po
Client
- Регистрация
- 27.08.2013
- Сообщения
- 848
- Благодарностей
- 531
- Баллы
- 93
Мне кажется самое верное решение. И ответ будет официальный!А вообще можно не гадать и просто написать в саппорт.
Мне кажется самое верное решение. И ответ будет официальный!А вообще можно не гадать и просто написать в саппорт.
Тут ты прав по той причине, что потокобезопасными коллекциями не могут быть листы, так как структура таких коллекций должна поддерживать добавление/извлечение элемента только с начала или с конца (ConcurrenQueue<T>, ConcurrenStack<T>, BlockingCollection<T>), поэтому коллекции в зеннопостере по дефолту не потокобезопасные, если говорить о кодеони не могут быть потокобезопасными, потому что их логика такого не позволяет. Например, чтобы взять строку с удалением, нужно отдельно взять, отдельно удалить. 2 действия. Если бы был отдельный метод, включающий в себя эти 2 действия, тогда он мог бы быть потокобезопасным
Интересный момент, не знал - не приходилось использовать их в таких случаях. Благодарю, поковыряю этот момент подробнее и после конкурса добавлю.если добавлять несколько проектов в ЗП из одного шаблона - статик переменные общего кода для них будут общие
В том и дело, что почти в каждом сниппете на форуме с локами - используются именно эти объекты. Представители ZennoLab в ответах на форуме так же замечены в неоднократном их использовании в примерах кода. Пруф - поиск по форуму. Соответственно, большая часть пользователей Zenno, кто использует локи (найдя нужный для себя сниппет на форуме) - используют именно эти стандартные объекты.Не пойму откуда вы взяли, что нужно вообще пользоваться этими объектами? Поискал в документации и не встретил упоминания, что в шаблонах нужно синхронизировать через них.
Сдается мне, что они созданы исключительно для внутренней логики ZP. Т.е. пока вся статья выглядит так, что вы изначально пользуетесь тем, чем не стоит, а затем поясняете какие из этого проблемы вытекают.
Скажите, а есть способ лочить когда используешь БД MySQL?Для популярных типов внешних ресурсов в ZennoPoster предусмотрено три объекта синхронизации, которые в C#-коде указываются в круглых скобках после lock:
SyncObjects.ListSyncer - для списков
SyncObjects.TableSyncer - для таблиц
SyncObjects.InputSyncer - для буфера обмена
В MySQL есть свои локи, ими лучше и лочить. На форуме есть ссылки и примеры, например тут.Скажите, а есть способ лочить когда используешь БД MySQL?
public static object SyncObject_accounts = new object();
// Имя файлов
string[] files = { @"keywords_3.txt", @"keywords_2.txt", @"keywords_1.txt"};
// Формирую путь к файлам
string path = string.Format(@"{0}\{1}", project.Directory, @"data");
// Проверяю есть ли папка - если нет - создаю
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
// Беру имя каждого файла по очереди
foreach (string file in files) {
lock (CommonCode.SyncObject_accounts){
// Проверяю существование файла
if(!File.Exists(string.Format(@"{0}\{1}", path, file))) {
// Если файл не найден - создаю
File.Create(string.Format(@"{0}\{1}", path, file));
}
// Если файл найден или создан - добавляю в файл текст
File.WriteAllText(string.Format(@"{0}\{1}", path, file), "текст", Encoding.UTF8);
}
}
06:12:02 Выполнение действия CSharp OwnCode Процесс не может получить доступ к файлу "D:\data\keywords_3.txt", так как этот файл используется другим процессом.
Распространяется, но скорее всего лучше использовать какой-нибудь StreamWriter, где явно будет закрытие файла. Я точно не берусь утверждать, но ощущение, что где-то остается работа с файлом. Далее он как список не используется ведь?Или, данный способ не распространяется на работу с файлами?
Нет, именно в этом виде который я привел в своем сообщении работает без каких либо дополнительных списков.Распространяется, но скорее всего лучше использовать какой-нибудь StreamWriter, где явно будет закрытие файла. Я точно не берусь утверждать, но ощущение, что где-то остается работа с файлом. Далее он как список не используется ведь?
Через 2-3 секунды выполняется успешно.А это убийственный глюк у зенки при работе с файлами. Я пытался найти решение под один шаблон но так и не нашел и уже не помню как вышел из ситуации. Попробуй после получения ошибки, через 2-3 сек. запустить по новой операцию обращения к файлу. Думаю удевишся. )
Мистика, не правда ли?Через 2-3 секунды выполняется успешно.
Потом последующий запуск - обратно ошибка.
Одел File.Create в using и заработалоМистика, не правда ли?
Да, разобраться не мешало бы и решить проблему. Не знаешь когда столкнешься с ней повторно и в каком месте.
// Имя файлов
string[] files = { @"keywords_3.txt", @"keywords_2.txt", @"keywords_1.txt"};
// Формирую путь к файлам
string path = string.Format(@"{0}\{1}", project.Directory, @"data");
// Проверяю есть ли папка - если нет - создаю
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
// Беру имя каждого файла по очереди
foreach (string file in files) {
// Проверяю существование файла
if(!File.Exists(string.Format(@"{0}\{1}", path, file)) {
// Если файл не найден - создаю
//File.Create(string.Format(@"{0}\{1}", path, file));
using ( File.Create(string.Format(@"{0}\{1}", path, file))) {};
}
// Если файл найден или создан - добавляю в файл текст
File.WriteAllText(string.Format(@"{0}\{1}", path, file), "текст", Encoding.UTF8);
}
Интересно) Что-то я даже не задумывался о таком "финте ушами". Расскажи потом как в многопотоке будет, если 1 и тот же файл кучей потоков обрабатывать таким способом (особенно интересует File.WriteAllText)Одел File.Create в using и заработало
зачем вообще проверять существование и создавать файл? убери этоОдел File.Create в using и заработало
Рабочий пример выглядит так.
Осталось еще в многопотоке проверить и определиться нужен ли этот объект синхронизации или не нужен.
C#:// Имя файлов string[] files = { @"keywords_3.txt", @"keywords_2.txt", @"keywords_1.txt"}; // Формирую путь к файлам string path = string.Format(@"{0}\{1}", project.Directory, @"data"); // Проверяю есть ли папка - если нет - создаю if (!Directory.Exists(path)) Directory.CreateDirectory(path); // Беру имя каждого файла по очереди foreach (string file in files) { // Проверяю существование файла if(!File.Exists(string.Format(@"{0}\{1}", path, file)) { // Если файл не найден - создаю //File.Create(string.Format(@"{0}\{1}", path, file)); using ( File.Create(string.Format(@"{0}\{1}", path, file))) {}; } // Если файл найден или создан - добавляю в файл текст File.WriteAllText(string.Format(@"{0}\{1}", path, file), "текст", Encoding.UTF8); }
Потому что не всегда может быть операция записать в файл, а может быть например сразу по пути перевести в base64 - и тогда гарантировано будет ошибка что мол нет файла.зачем вообще проверять существование и создавать файл? убери это
Наверно в многопотоке придется все-таки этот объект синхронизации использовать.Интересно) Что-то я даже не задумывался о таком "финте ушами". Расскажи потом как в многопотоке будет, если 1 и тот же файл кучей потоков обрабатывать таким способом (особенно интересует File.WriteAllText)
Добавлю, что мистики никакой нет, просто метод Create возвращает объект FileStream, для возможности дальнейшей работы с файлом.Вопрос, что я делаю не так?
File.Create(path).Close();
А потом оказалось что выдает ошибку и решил разобраться почему этот lock не спасает.
Вот только впринципе логично - если должен спасать от многопотока, то явно не должен от ошибок в логике кода и не понимания, как вообще правильно работать с файлами в C#.
Пожалуйста, объясните кто-нибудь на пальцах, как сделать это в Code Creator?Необходимо создать свои собственные объекты синхронизации в Общем коде. По умолчанию там даже один уже есть:
Вставить такие строчки объвления в любой подходящий класс, точно так же, как в Общем коде ProjectMaker.Пожалуйста, объясните кто-нибудь на пальцах, как сделать это в Code Creator?
lock (Lock.ProxyList)
{
//... Тут действия со списком прокси, которые необходимо заблокировать
}
Можно использовать стандартные локи, или вынести свои в dll, подключив её к этим шаблонам (т.е. чтобы локи были как внешний общий ресурс).для лока файлов которые используют разные шаблоны - это годится или это не тот велосипед?
Если вас не затруднит, то есть пример либы?Можно использовать стандартные локи, или вынести свои в dll, подключив её к этим шаблонам (т.е. чтобы локи были как внешний общий ресурс).
Этому человеку кто нибудь помог?!Братцы, подскажите как в локе "прочитать файл" положить в переменную и удалить?
проблема описана тут
На форуме по-моему несколько тем было по созданию либ в Visual Studio (вот например +- статья по теме). В данном случае нужно просто перенести локи из общего кода в либу, либу собрать и подключить к шаблонам - и можно пользоваться локами из либы.Если вас не затруднит, то есть пример либы?
Насколько помню, для разных шаблонов это будут разные локи (так как и блок общего кода у каждого будет свой). В копиях одного и того же шаблона локи, соответственно, будут так работать (блок общего кода будет один на все копии шаба).и еще момент, а если в общий код разных шахов добавить один и тот же код Лока?
Не знаю, кто такое пишет. Но вот этот лок, отлично работает со списками.Начал делать лок
lock (SyncObjects.ListSyncer)
а там пишут, что он устарел и нужно использовать новый лок
lock (FileSyncObjects.ListSyncer)
lock(SyncObjects.ListSyncer)
Команда зеннолаба.Не знаю, кто такое пишет.
public class SyncObjects
{
[Obsolete("Use FileSyncObjects.ListSyncer instead.")]
public static readonly object ListSyncer;
[Obsolete("Use FileSyncObjects.TableSyncer instead.")]
public static readonly object TableSyncer;
public static readonly object InputSyncer;
public SyncObjects();
}
Тогда извиняюсь. Подождем более компетентного ответа.Команда зеннолаба.