Вопрос разработки: несколько потоков, нуждающихся в доступе к файлам журналов для чтения / записи в приложении c # - PullRequest
3 голосов
/ 31 августа 2011

У меня проблемы с несколькими потоками в приложении c #, которые пытаются прочитать и / или записать в файл журнала. Иногда возникает исключение, и я подозреваю, что это происходит из-за столкновений. Есть ли хороший способ гарантировать эксклюзивный доступ для каждого потока при открытии файлов?

Ответы [ 6 ]

1 голос
/ 31 августа 2011

Самое простое, что можно сделать, - это использовать каркас журналирования, такой как log4net, который является поточно-ориентированным из коробки.

Если по какой-то причине вы не можете использовать каркас ведения журналов, вам придется использовать один из методов синхронизации потоков, упомянутых выше, и управлять доступом самостоятельно.

1 голос
/ 31 августа 2011

Блокировка, вероятно, является более подходящим способом здесь.Если производительность критична, вы можете прибегнуть к какой-либо очереди сообщений журнала, например, ConcurrentQueue<T>, которая должна быть полностью оптимизирована для одновременного чтения / записи вместе с шаблоном потребителя производителя.

1 голос
/ 31 августа 2011

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

private static readonly object syncObject = new object();

// .. when ready to write to a file in a method
lock(syncObject)
{
    // write to file here, 
    // no other thread is able to write to the file while this is locked
}

Это синхронизирует запись файла и гарантирует, что у вас не будет "коллизий" записи.

0 голосов
/ 01 сентября 2011

А как насчет потока только для ведения журнала, который обменивается данными через параллельную очередь и события «тонкого ожидания»?

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

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

Выможет читать файлы из этой очереди с сообщениями в этот поток (что-то вроде вызова или отправки сообщения).

0 голосов
/ 31 августа 2011

Файловые системы обычно имеют встроенные системы блокировки, поэтому, если все ваши потоки не используют один и тот же объект Stream, с вами все будет в порядке. Если они , а не , установите собственную блокировку для каждого доступа к файлу (обычно одновременное чтение может быть выполнено, но если вы не хотите использовать разные потоки для каждого, это невозможно):

lock(streamObject) {
    // access the file here
}

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

Обратите внимание, что это не считается созданием нового потока:

using(StreamReader sr = new StreamReader(theBaseStream)) {
 ...

потому что он все еще использует тот же базовый Stream объект.

0 голосов
/ 31 августа 2011

Вы можете использовать объект для блокировки файла.

Введите свой код доступа к файлу в lock(object) { your file access code ... }, чтобы он не выполнялся одновременно.

...