2010-06-14 3 views
75

В моем приложении У меня есть статический метод, который вызывается из нескольких потоков одновременно. Есть ли опасность, что мои данные перепутаны?C#: Что делать, если статический метод вызывается из нескольких потоков?

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

ответ

74

Переменные, объявленные внутри методов (за исключением исключенных «захваченных« переменных), изолированы, поэтому вы не получите никаких неотъемлемых проблем; однако, если ваш статический метод обращается к любому совместному состоянию, все ставки отключены.

Примеров совместно-состояния будут:

  • статических поля
  • объектов, доступных из общей кэш-памяти (не сериализованной)
  • данные, полученный с помощью входных параметров (и состояния на этих объектах) , если это возможно, что несколько потоков касаются того же объекта (ов)

Если у вас есть общие состояния, вы должны либо:

  • позаботятся не мутировать состояние, когда он может быть общим (лучше: использовать неизменные объекты для представления состояния, и сделать снимок состояния в локальную переменную - то есть, а не ссылаться на whatever.SomeData несколько раз, вы читали whatever.SomeDataодин раз в локальную переменную, а затем просто используйте переменную - обратите внимание, что это помогает только для неизменяемого состояния!)
  • синхронизировать доступ к данным (все потоки должны синхронизироваться) - либо взаимоисключающий, либо (более гранулярный) считыватель/запись
+1

взгляните на это http://msdn.microsoft.com/library/c5kehkcz(VS .80) .aspx –

+1

@ Diego - этот комментарий предназначен для меня или для @ Холли? –

+0

To Holli, просто чтобы добавить практическую информацию к вашему ответу. –

9

Статические методы должны быть точными для нескольких потоков.

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

+0

Ключевое слово здесь - синхронизация :-) –

+0

Чтение в порядке, чтобы произойти одновременно, но чтение и запись одновременно приведет к неожиданному поведению – Freestyle076

4

MSDN Всегда говорит:

Любые публичные статические (Shared in Visual Basic) элементы этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.

Edit: Как ребята здесь говорят, это не всегда так, и ясно, что это относится и к классам, разработанных таким образом, в BCL, не созданных пользователем классов, если это не относится.

16

Да, это просто удача. ;)

Не имеет значения, является ли метод статическим или нет, имеет значение, если данные являются статическими или нет.

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

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

Смежные вопросы