2012-02-07 42 views
3

我使用Unity 2.0在我的項目中,我讀了很多文件在代碼Parallel.ForEach塊內的同一時間:UNITY:如何使用構造函數注入實現線程安全的Container.Resolve()函數?

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

解析(新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' 

這是當同一文件在同一時間下載 - 解決功能與在同一時間同一參數創建兩個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>(); 
+5

這並不直接回答你的問題,但我認爲你可能做錯了。你的類應該注入一個IMsBuildProjectLoader,並且在你的循環中,你應該調用IMsBuildProjectLoader上的一個方法,該方法將文件名作爲參數。然後應該將線程安全性融入到IMsBuildProjectLoader的實現中。我的$ 0.02。 – BFree 2012-02-07 16:33:18

+0

是的,那是另一種選擇。謝謝 – Ludwo 2012-02-07 19:54:33

回答

0

解決實際線程安全(或者說在微軟P & P的傢伙)。 可能不是線程安全的是執行MsBuildProjectLoader,或者更具體地說它是構造函數。 你可能會簡單地以相同的異步方式使用

您不包括負載的實施創造MsBuildProjectLoader的新實例,但根據異常蹣跚同樣的問題,我會假設它操縱共享或靜態字典以非線程安全的方式。 如果出現這種情況,應該使該字典線程安全(例如,將其替換爲ConcurrentDictionary)。