public override SdkResult ResolveSdk(int submissionId, SdkReference sdk, LoggingContext loggingContext, ElementLocation sdkReferenceLocation, SdkEnv sdkEnv, bool interactive) { SdkResult result; if (Traits.Instance.EscapeHatches.DisableSdkResolutionCache) { result = base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, sdkEnv, interactive); } else { // Get the dictionary for the specified submission if one is already added otherwise create a new dictionary for the submission. ConcurrentDictionary <string, Lazy <SdkResult> > cached = _cache.GetOrAdd(submissionId, new ConcurrentDictionary <string, Lazy <SdkResult> >(MSBuildNameIgnoreCaseComparer.Default)); /* * Get a Lazy<SdkResult> if available, otherwise create a Lazy<SdkResult> which will resolve the SDK with the SdkResolverService.Instance. If multiple projects are attempting to resolve * the same SDK, they will all get back the same Lazy<SdkResult> which ensures that a single build submission resolves each unique SDK only one time. */ Lazy <SdkResult> resultLazy = cached.GetOrAdd( sdk.Name, key => new Lazy <SdkResult>(() => base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, sdkEnv, interactive))); // Get the lazy value which will block all waiting threads until the SDK is resolved at least once while subsequent calls get cached results. result = resultLazy.Value; } if (result != null && !SdkResolverService.IsReferenceSameVersion(sdk, result.SdkReference.Version) && !SdkResolverService.IsReferenceSameVersion(sdk, result.Version)) { // MSB4240: Multiple versions of the same SDK "{0}" cannot be specified. The previously resolved SDK version "{1}" from location "{2}" will be used and the version "{3}" will be ignored. loggingContext.LogWarning(null, new BuildEventFileInfo(sdkReferenceLocation), "ReferencingMultipleVersionsOfTheSameSdk", sdk.Name, result.Version, result.ElementLocation, sdk.Version); } return(result); }
public SdkResult ResolveSdk(int submissionId, SdkReference sdk, LoggingContext loggingContext, ElementLocation sdkReferenceLocation, string solutionPath, string projectPath) { SdkResult result; if (Traits.Instance.EscapeHatches.DisableSdkResolutionCache) { result = _wrappedService.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath); } else { // Get the dictionary for the specified submission if one is already added otherwise create a new dictionary for the submission. ConcurrentDictionary <string, SdkResult> cached = _cache.GetOrAdd(submissionId, new ConcurrentDictionary <string, SdkResult>(MSBuildNameIgnoreCaseComparer.Default)); /* * Get a cached result if available, otherwise resolve the SDK with the SdkResolverService.Instance. If multiple projects are attempting to resolve * the same SDK, they will all block while the first one resolves. Blocked requests will then get the cached result. This ensures that a single * build submission resolves each unique SDK only one time. */ result = cached.GetOrAdd( sdk.Name, key => _wrappedService.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath)); } if (result != null && !SdkResolverService.IsReferenceSameVersion(sdk, result.SdkReference.Version) && !SdkResolverService.IsReferenceSameVersion(sdk, result.Version)) { // MSB4240: Multiple versions of the same SDK "{0}" cannot be specified. The previously resolved SDK version "{1}" from location "{2}" will be used and the version "{3}" will be ignored. loggingContext.LogWarning(null, new BuildEventFileInfo(sdkReferenceLocation), "ReferencingMultipleVersionsOfTheSameSdk", sdk.Name, result.Version, result.ElementLocation, sdk.Version); } return(result); }
/// <inheritdoc cref="ISdkResolverService.ResolveSdk"/> public override SdkResult ResolveSdk(int submissionId, SdkReference sdk, LoggingContext loggingContext, ElementLocation sdkReferenceLocation, SdkEnv sdkEnv, bool interactive) { // Get a cached response if possible, otherwise send the request var sdkResult = _responseCache.GetOrAdd( sdk.Name, key => { var result = RequestSdkPathFromMainNode(submissionId, sdk, loggingContext, sdkReferenceLocation, sdkEnv.solutionPath, sdkEnv.projectPath, interactive); return(new SdkResult(null, result.Path, result.Version, null)); }); if (sdkResult.Version != null && !SdkResolverService.IsReferenceSameVersion(sdk, sdkResult.Version)) { // MSB4240: Multiple versions of the same SDK "{0}" cannot be specified. The SDK version "{1}" already specified by "{2}" will be used and the version "{3}" will be ignored. loggingContext.LogWarning(null, new BuildEventFileInfo(sdkReferenceLocation), "ReferencingMultipleVersionsOfTheSameSdk", sdk.Name, sdkResult.Version, sdkResult.ElementLocation, sdk.Version); } return(sdkResult); }