Любые советы по многопоточности + дизайн для следующих случаев - PullRequest
2 голосов
/ 19 марта 2009

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

Некоторые из ситуаций, которые я вижу, могут вызвать проблемы, и я не уверен, что лучший способ разрешить их:

1) У меня есть класс, который принимает IEnumerable и использует ToList для создания IList. T - это класс, объявленный как public в моей сборке. После запуска асинхронного процесса этот IList используется для создания новой коллекции, однако в этот момент вызывающая сборка может изменять исходные T, используемые для создания моей новой внутренней коллекции.

2) У меня есть логическое свойство, которое я ожидаю, что пользователь будет использовать в цикле опроса. Я вполне уверен, что это не будет проблемой для меня при установке свойства в моей сборке?

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

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

Заранее благодарим за любую помощь!

Ian

Ответы [ 3 ]

2 голосов
/ 19 марта 2009

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

2) Создайте базовую переменную volatile, чтобы обновления отображались во всех потоках

3) Нам нужно больше информации, чтобы иметь возможность комментировать.

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

1 голос
/ 19 марта 2009

2: следите за volatile ( см. Здесь , например, почему); и не делайте "тугие" петли. Сигналы (такие как Monitor.Pulse или ManualResetEvent и т. Д.) Часто являются предпочтительными

4: если это для целей отображения, вам нужно перенести их обратно в поток пользовательского интерфейса

0 голосов
/ 19 марта 2009

Спасибо, ребята,

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

2) Ключевое слово volatile выглядит как то, что мне определенно нужно, поэтому добавлю это.

3) У меня будут запущены два потока, оба из которых должны получить доступ к Collection . Как только они получат эту коллекцию, они будут широко ее использовать, а также изменят различные свойства для каждого экземпляра U. После того, как они закончили, они сохранят несколько простых свойств (например, Guid), выбросят коллекцию и потребуется начать заново. Поэтому я думаю, что сначала необходимо создать ReadOnlyCollection , а затем для каждого из этих потоков, когда начнется обработка, они запустят некоторую форму метода Clone и перетекут вывод в новый IList для пример, который они сделают, они продолжат.

4) Это полезно, Джон, обработка событий может быть вызвана из нескольких потоков, поэтому я обязательно что-то использую в этом направлении.

...