UNITY: Как реализовать потокобезопасную функцию Container.Resolve () с помощью инжектора конструктора? - PullRequest
3 голосов
/ 07 февраля 2012

Я использую Unity 2.0 в своем проекте, где одновременно читаю много файлов внутри блока кода Parallel.ForEach:

Parallel.ForEach(files, currentFile =>
{
    using(IMsBuildProjectLoader msBuildProject = Container.Resolve<IMsBuildProjectLoader>(new ParameterOverride("projectFileName", currentFile)))
    {
        // file processing
    }
}

Resolve (новая функция ParameterOverride ("projectFileName", currentFile) иногда генерирует ResolutionFailedException:

ResolutionFailedException: Resolution of the dependency failed, 
type = "Porthus.Build.Common.Interfaces.IMsBuildProjectLoader", name = "(none)". 
Exception occurred while: Calling constructor XXX.Build.Common.Types.MsBuildProjectLoader(System.String projectFileName). 
Exception is: ArgumentException - Item has already been added. Key in dictionary: 'xxx'  Key being added: 'xxx'

Это когда один и тот же файл загружается одновременно - функция Resolve создает два экземпляра IMsBuildProjectLoader с одним и тем же параметром одновременно. Это не может быть решено с помощью фильтра files.Distinct (). Выше код является только примером кода, чтобы объяснить мою проблему.

Вопрос : Как реализовать поточно-ориентированную функцию UnityContainer.Resolve? Можно ли сделать это с помощью некоторого класса расширения Unity?

IMsBuildProjectLoader

public interface IMsBuildProjectLoader : IDisposable
{
}

MsBuildProjectLoader

public class MsBuildProjectLoader : Project, IMsBuildProjectLoader
{
    public MsBuildProjectLoader(string projectFileName)
        : base()
    {
        // Load the contents of the specified project file.
        Load(projectFileName);
    }
}

MsBuildProjectLoader регистрируется следующим образом:

container.RegisterType<IMsBuildProjectLoader, MsBuildProjectLoader>();

1 Ответ

0 голосов
/ 21 декабря 2014

Resolve на самом деле поточно-ориентированный (или, так сказать, ребята из Microsoft P & P). Что, вероятно, не является потокобезопасным, так это реализация MsBuildProjectLoader или, более конкретно, его конструктор. Вы, вероятно, столкнетесь с той же проблемой, просто создав новые экземпляры MsBuildProjectLoader, используя new в том же асинхронном режиме

Вы не включили реализацию Load, но в соответствии с исключением я бы предположил, что он манипулирует совместно используемым или статическим словарем не поточно-ориентированным способом. Если это так, вы должны сделать этот поток словаря безопасным (например, заменив его на ConcurrentDictionary ).

...