2013-11-25 44 views
0

我正在並行運行一些單元測試。每個單元測試調用一些代碼,觸發SSDT數據庫項目的一個MSBuild部署:以編程方式構建項目時出現「此集合爲只讀」異常

void Deploy(string projectPath, string publishProfilePath, ILogger logger) 
{ 
    var project = ProjectCollection.GlobalProjectCollection.LoadProject("projectPath); 

    Projects.SetGlobalProperty("Configuration", "Debug"); 
    Projects.SetGlobalProperty("SqlPublishProfilePath", publishProfilePath); 
    var targets = new[] { "Build", "Publish" }; 

    project.Build(targets, new[] { logger }); 
} 

這種方法的最後一行拋出InvalidOperationException以下消息:

此集合爲只讀。

這裏的調用堆棧跟蹤的相關部分:

at Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args) 
    at Microsoft.Build.Collections.RetrievableEntryHashSet`1.AddEvenIfPresent(T value) 
    at Microsoft.Build.Evaluation.Project.Data.AddTarget(ProjectTargetInstance target) 
    at Microsoft.Build.Evaluation.Evaluator`4.ReadTargetElement(ProjectTargetElement targetElement, LinkedList`1 activeTargetsByEvaluationOrder, Dictionary`2 activeTargets) 
    at Microsoft.Build.Evaluation.Evaluator`4.Evaluate() 
    at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(IEvaluatorData`4 data, ProjectRootElement root, ProjectLoadSettings loadSettings, Int32 maxNodeCount, PropertyDictionary`1 environmentProperties, ILoggingService loggingService, IItemFactory`2 itemFactory, IToolsetProvider toolsetProvider, ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext, ProjectInstance projectInstanceIfAnyForDebuggerOnly) 
    at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation) 
    at Microsoft.Build.Evaluation.Project.CreateProjectInstance(ILoggingService loggingServiceForEvaluation, ProjectInstanceSettings settings) 
    at Microsoft.Build.Evaluation.Project.Build(String[] targets, IEnumerable`1 loggers, IEnumerable`1 remoteLoggers) 
    at Microsoft.Build.Evaluation.Project.Build(String[] targets, IEnumerable`1 loggers) 

似乎爲Build方法的文檔並沒有提到這一點。此代碼已經工作過。

回答

0

我懷疑MSBuild在這種方式下不是線程安全的。

當我使用lock做我的代碼線程安全的防止多個同時調用它不再發生的問題:

void Deploy(string projectPath, string publishProfilePath, ILogger logger) 
{ 
    lock (deployLock) 
    { 
     //Implementation 
    } 
} 

object deployLock = new object(); 
相關問題