С#: Что делать, если статический метод вызывается из нескольких потоков?
В моем приложении у меня есть статический метод, который вызывается из нескольких потоков одновременно. Есть ли опасность, что мои данные перепутаны?
В моей первой попытке метод не был статичным, и я создавал несколько экземпляров класса. В этом случае мои данные каким-то образом перепутались. Я не уверен, как это происходит, потому что это происходит только иногда. Я все еще отлаживаю.
Но теперь метод статический, у меня пока нет проблем. Возможно, это просто удача. Я не знаю точно.
Ответы
Ответ 1
Переменные, объявленные внутри методов (с возможным исключением "захваченных" переменных) изолированы, поэтому вы не получите никаких неотъемлемых проблем; однако, если ваш статический метод обращается к любому состоянию общего доступа, все ставки отключены.
Примеры общего состояния:
- статические поля
- объекты, получаемые из общего кеша (несериализованные)
- данные, полученные через входные параметры (и состояние на этих объектах), если возможно, что несколько потоков касаются одного и того же объекта (ов)
Если у вас есть общее состояние, вы должны:
- будьте осторожны, чтобы не мутировать состояние после его совместного использования (лучше: использовать неизменяемые объекты для представления состояния и повторно делать снимок состояния в локальной переменной, то есть вместо ссылки
whatever.SomeData
, читать whatever.SomeData
один раз в локальную переменную, а затем просто используйте переменную - обратите внимание, что это помогает только для неизменяемого состояния!)
- синхронизировать доступ к данным (все потоки должны синхронизировать) - либо взаимоисключающий, либо (более подробный) считыватель/запись
Ответ 2
Да, это просто удача.;)
Не имеет значения, является ли метод статическим или нет, имеет значение, если данные являются статическими или нет.
Если в каждом потоке есть отдельный экземпляр класса с собственным набором данных, нет никакого риска смешивания данных. Если данные статичны, существует только один набор данных, и все потоки имеют одни и те же данные, поэтому нет возможности не смешивать их.
Когда ваши данные в отдельных экземплярах все еще смешиваются, это, скорее всего, потому, что данные не являются отдельными.
Ответ 3
Статические методы должны быть точными для нескольких потоков.
Статические данные, с другой стороны, могут вызвать проблему, потому что необходимо контролировать попытки доступа к тем же данным из разных потоков, чтобы гарантировать, что только один поток за раз читает или записывает данные.
Ответ 4
MSDN Всегда говорит:
Любые публичные статические (Shared in Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.
Edit:
Как говорят ребята, это не всегда так, и это явно относится к классам, разработанным таким образом в BCL, а не к созданным пользователем классам, где это не применяется.