Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4cf43f3

Browse files
saulKevinRansom
authored andcommitted
Improve solution load performance (dotnet#2133)
* Reduce number of calls to ComputeSourcesAndFlags, add wait indicator to some long running project tasks* Project close might throw an exception too, so bundle them both up and re-raise them as an aggregate exception* Added IVsSolutionBuildManager5 and IVsThreadedWaitDialogFactory to VS mocks to fix tests* Hide some types/modules that were accidentally added to the public API surface
1 parentac10de1 commit4cf43f3

File tree

10 files changed

+194
-36
lines changed

10 files changed

+194
-36
lines changed

‎vsintegration/src/FSharp.ProjectSystem.Base/Project/OutputGroup.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public virtual void Refresh()
113113
varresult=newBuildResult(MSBuildResult.Failed,null);
114114
if(project.ProjectMgr.BuildProject.Targets.ContainsKey(ProjectFileConstants.AllProjectOutputGroups))
115115
{
116-
result=project.InvokeMsBuild(ProjectFileConstants.AllProjectOutputGroups,false/*isBeingCalledByComputeSourcesAndFlags*/);
116+
result=project.InvokeMsBuild(ProjectFileConstants.AllProjectOutputGroups);
117117
if(!result.IsSuccessful)
118118
{
119119
// we could not compute it, probably because there is a real build going on right now

‎vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.cs‎

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,7 +2268,7 @@ public string GetBuildMacroValue(string propertyName)
22682268
{
22692269
this.SetCurrentConfiguration();
22702270
this.UpdateMSBuildState();
2271-
varresult=this.InvokeMsBuild(ProjectFileConstants.AllProjectOutputGroups,false);
2271+
varresult=this.InvokeMsBuild(ProjectFileConstants.AllProjectOutputGroups);
22722272
if(result.ProjectInstance!=null)returnresult.ProjectInstance.GetPropertyValue(propertyName);
22732273
};
22742274
returnthis.GetProjectProperty(propertyName,true);
@@ -2947,9 +2947,7 @@ public virtual void Reload()
29472947
this.ProcessCustomBuildActions();
29482948

29492949
this.ProcessFilesAndFolders();
2950-
2951-
2952-
2950+
29532951
this.LoadNonBuildInformation();
29542952

29552953
this.InitSccInfo();
@@ -3142,11 +3140,6 @@ internal virtual void SetBuildConfigurationProperties(ConfigCanonicalName config
31423140
/// <returns>Result from executing the target (success/failure)</returns>
31433141
[SuppressMessage("Microsoft.Naming","CA1709:IdentifiersShouldBeCasedCorrectly",MessageId="Ms")]
31443142
internalvirtualBuildResultInvokeMsBuild(stringtarget,IEnumerable<KeyValuePair<string,string>>extraProperties=null)
3145-
{
3146-
returnInvokeMsBuild(target,false,extraProperties);
3147-
}
3148-
3149-
internalvirtualBuildResultInvokeMsBuild(stringtarget,boolisBeingCalledByComputeSourcesAndFlags,IEnumerable<KeyValuePair<string,string>>extraProperties=null)
31503143
{
31513144
UIThread.MustBeCalledFromUIThread();
31523145
ProjectInstanceprojectInstance=null;
@@ -3156,10 +3149,6 @@ internal virtual BuildResult InvokeMsBuild(string target, bool isBeingCalledByCo
31563149
if(submission!=null)
31573150
{
31583151
MSBuildResultresult=(submission.BuildResult.OverallResult==BuildResultCode.Success)?MSBuildResult.Successful:MSBuildResult.Failed;
3159-
if(!isBeingCalledByComputeSourcesAndFlags)
3160-
{
3161-
this.ComputeSourcesAndFlags();
3162-
}
31633152
returnnewBuildResult(result,projectInstance);
31643153
}
31653154
else

‎vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs‎

Lines changed: 96 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
440440
let mutableupdateSolnEventsHandle=0u
441441
let mutableupdateSolnEventsHandle2=0u
442442
let mutableupdateSolnEventsHandle3=0u
443+
let mutableupdateSolnEventsHandle4=0u
443444

444445
let mutabletrackProjectRetargetingCookie=0u
445446

@@ -586,14 +587,26 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
586587
letlistener=new SolutionEventsListener(this)
587588

588589
letbuildMgr= this.Site.GetService(typeof<SVsSolutionBuildManager>):?> IVsSolutionBuildManager
590+
if updateSolnEventsHandle<>0uthen
591+
buildMgr.UnadviseUpdateSolutionEvents(updateSolnEventsHandle)|> ignore
589592
buildMgr.AdviseUpdateSolutionEvents((listener:> IVsUpdateSolutionEvents),&updateSolnEventsHandle)|> ignore
590593
letbuildMgr2= this.Site.GetService(typeof<SVsSolutionBuildManager>):?> IVsSolutionBuildManager2
594+
if updateSolnEventsHandle2<>0uthen
595+
buildMgr2.UnadviseUpdateSolutionEvents(updateSolnEventsHandle2)|> ignore
591596
buildMgr2.AdviseUpdateSolutionEvents((listener:> IVsUpdateSolutionEvents2),&updateSolnEventsHandle2)|> ignore
592597
letbuildMgr3= this.Site.GetService(typeof<SVsSolutionBuildManager>):?> IVsSolutionBuildManager3
598+
if updateSolnEventsHandle3<>0uthen
599+
buildMgr3.UnadviseUpdateSolutionEvents3(updateSolnEventsHandle3)|> ignore
593600
buildMgr3.AdviseUpdateSolutionEvents3((listener:> IVsUpdateSolutionEvents3),&updateSolnEventsHandle3)|> ignore
601+
letbuildMgr5= this.Site.GetService(typeof<SVsSolutionBuildManager>):?> IVsSolutionBuildManager5
602+
if updateSolnEventsHandle4<>0uthen
603+
buildMgr5.UnadviseUpdateSolutionEvents4(updateSolnEventsHandle4)|> ignore
604+
buildMgr5.AdviseUpdateSolutionEvents4((listener:> IVsUpdateSolutionEvents4),&updateSolnEventsHandle4)|> ignore
594605

595606
// Register for project retargeting events
596607
letsTrackProjectRetargeting= this.Site.GetService(typeof<SVsTrackProjectRetargeting>):?> IVsTrackProjectRetargeting
608+
if trackProjectRetargetingCookie<>0uthen
609+
sTrackProjectRetargeting.UnadviseTrackProjectRetargetingEvents(trackProjectRetargetingCookie)|> ignore
597610
sTrackProjectRetargeting.AdviseTrackProjectRetargetingEvents((listener:> IVsTrackProjectRetargetingEvents),&trackProjectRetargetingCookie)|> ignore
598611

599612
isInCommandLineMode<-
@@ -616,6 +629,8 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
616629
buildMgr2.UnadviseUpdateSolutionEvents(updateSolnEventsHandle2)|> ignore
617630
letbuildMgr3= this.Site.GetService(typeof<SVsSolutionBuildManager>):?> IVsSolutionBuildManager3
618631
buildMgr3.UnadviseUpdateSolutionEvents3(updateSolnEventsHandle3)|> ignore
632+
letbuildMgr5= this.Site.GetService(typeof<SVsSolutionBuildManager>):?> IVsSolutionBuildManager5
633+
buildMgr5.UnadviseUpdateSolutionEvents4(updateSolnEventsHandle4)|> ignore
619634

620635
letdocumentTracker= this.Site.GetService(typeof<SVsTrackProjectDocuments>):?> IVsTrackProjectDocuments2
621636
documentTracker.UnadviseTrackProjectDocumentsEvents(trackDocumentsHandle)|> ignore
@@ -1328,12 +1343,27 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
13281343
yield System.IO.Path.GetFullPath(System.IO.Path.Combine(projectFolder, i.EvaluatedInclude))
13291344
|]
13301345
memberx.GetCompileItems()=letsources,_= sourcesAndFlags.Valuein sources
1331-
memberx.GetCompileFlags()=let_,flags= sourcesAndFlags.Valuein flags
1346+
memberx.GetCompileFlags()=let_,flags= sourcesAndFlags.Valuein flags
13321347

13331348
overridex.ComputeSourcesAndFlags()=
1349+
13341350
if x.IsInBatchUpdate|| box x.BuildProject=nullthen()
13351351
else
13361352
ifnot(inMidstOfReloading)&&not(VsBuildManagerAccessorExtensionMethods.IsInProgress(accessor))then
1353+
1354+
use waitDialog=
1355+
{
1356+
WaitCaption= FSharpSR.GetString FSharpSR.ProductName
1357+
WaitMessage= FSharpSR.GetString FSharpSR.ComputingSourcesAndFlags
1358+
ProgressText= Some x.ProjectFile
1359+
StatusBmpAnim=null
1360+
StatusBarText= None
1361+
DelayToShowDialogSecs=1
1362+
IsCancelable=false
1363+
ShowMarqueeProgress=true
1364+
}
1365+
|> WaitDialog.start x.Site
1366+
13371367
// REVIEW CompilerFlags will be stale since last 'save' of MSBuild .fsproj file - can we do better?
13381368
try
13391369
actuallyBuild<-false
@@ -1357,10 +1387,11 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
13571387
// If property is not set - msbuild will resolve only primary dependencies,
13581388
// and compiler will be very unhappy when during processing of referenced assembly it will discover that all fundamental types should be
13591389
// taken from System.Runtime that is not supplied
1360-
let_= x.InvokeMsBuild("Compile", isBeingCalledByComputeSourcesAndFlags=true, extraProperties=[KeyValuePair("_ResolveReferenceDependencies","true")])
1390+
1391+
let_= x.InvokeMsBuild("Compile", extraProperties=[KeyValuePair("_ResolveReferenceDependencies","true")])
13611392
sourcesAndFlagsNotifier.Notify()
13621393
finally
1363-
actuallyBuild<-true
1394+
actuallyBuild<-true
13641395

13651396
memberinternalx.DetermineRuntimeAndSKU(targetFrameworkMoniker:string)=
13661397
letframeworkName=new System.Runtime.Versioning.FrameworkName(targetFrameworkMoniker)
@@ -1439,7 +1470,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
14391470
memberips.DescriptionOfProject()=
14401471
letsources,flags= sourcesAndFlags.Value
14411472
sprintf"Project System: flags(%A) sources:\n%A" flags sources
1442-
memberips.CompilerFlags()=let_,flags= sourcesAndFlags.Valuein flags
1473+
memberips.CompilerFlags()=x.GetCompileFlags()
14431474
memberips.ProjectFileName()= MSBuildProject.GetFullPath(x.BuildProject)
14441475
memberips.ErrorListTaskProvider()= Some(x.TaskProvider)
14451476
memberips.ErrorListTaskReporter()= Some(x.TaskReporter)
@@ -1595,6 +1626,11 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
15951626
memberx.SetSpecificEditorProperty(_mkDocument:string,_propid:int,_value:obj)=
15961627
VSConstants.E_NOTIMPL
15971628
end
1629+
1630+
typeinternalActiveCfgBatchUpdateState=
1631+
| NonBatch
1632+
| BatchWaiting
1633+
| BatchDone
15981634

15991635
// Why is this a separate class, rather than an interface implemented on
16001636
// FSharpProjectNode? Because, at the time of initial registration of this
@@ -1605,7 +1641,14 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
16051641
// class means we have a separate object to CCW wrap, avoiding the problematic
16061642
// "double CCW-wrapping" of the same object.
16071643
typeinternalSolutionEventsListener(projNode)=
1608-
let mutablequeuedWork:option<list<FSharpProjectNode>>= None
1644+
1645+
let mutablewaitDialog:IDisposable option= None
1646+
1647+
// During batch active project configuration changes, make sure we only run CSAF once
1648+
// per batch. Before this change, OnActiveProjectCfgChange was being called twice per
1649+
// batch per project.
1650+
let mutablebatchState= NonBatch
1651+
16091652
// The CCW wrapper seems to prevent an object-identity test, so we determine whether
16101653
// two IVsHierarchy objects are equal by comparing their captions. (It's ok if this
16111654
// occasionally yields false positives, as this just means we may do a little extra
@@ -1620,14 +1663,16 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
16201663
o:?> System.String
16211664
else
16221665
null: System.String
1666+
16231667
letOnActiveProjectCfgChange(pIVsHierarchy)=
1624-
if GetCaption(pIVsHierarchy)= GetCaption(projNode.InteropSafeIVsHierarchy)then
1668+
if GetCaption(pIVsHierarchy)= GetCaption(projNode.InteropSafeIVsHierarchy)&& batchState<> BatchDonethen
16251669
projNode.SetProjectFileDirty(projNode.IsProjectFileDirty)
1626-
projNode.ComputeSourcesAndFlags()// REVIEW: It looks like ComputeSourcesAndFlags is called twice. Once on this line and then again because it is added to 'queuedWork' below.
1627-
match queuedWorkwith
1628-
| Some(l)-> queuedWork<- Some( projNode:: l)
1629-
| None->()
1670+
projNode.ComputeSourcesAndFlags()
1671+
1672+
if batchState= BatchWaitingthen
1673+
batchState<- BatchDone
16301674
VSConstants.S_OK
1675+
16311676
letUpdateConfig(pHierProj)=
16321677
// By default, the F# project system keeps its own internal Configuration and Platform in sync with the current active
16331678
// Configuration and Platform by listening for OnActiveProjectCfgChange events. However there is one case where the
@@ -1640,6 +1685,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
16401685
MSBuildProject.SetGlobalProperty(projNode.BuildProject, ProjectFileConstants.Configuration, currentConfigName.ConfigName)
16411686
MSBuildProject.SetGlobalProperty(projNode.BuildProject, ProjectFileConstants.Platform, currentConfigName.MSBuildPlatform)
16421687
projNode.UpdateMSBuildState()
1688+
16431689
interface IVsUpdateSolutionEventswith
16441690
memberx.UpdateSolution_Begin(pfCancelUpdate)=
16451691
VSConstants.S_OK
@@ -1651,6 +1697,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
16511697
VSConstants.S_OK
16521698
memberx.OnActiveProjectCfgChange(pIVsHierarchy)=
16531699
OnActiveProjectCfgChange(pIVsHierarchy)
1700+
16541701
interface IVsUpdateSolutionEvents2with
16551702
memberx.UpdateSolution_Begin(pfCancelUpdate)=
16561703
VSConstants.S_OK
@@ -1668,17 +1715,51 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
16681715
memberx.UpdateProjectCfg_Done(pHierProj,_pCfgProj,_pCfgSln,_dwAction,_fSuccess,_fCancel)=
16691716
UpdateConfig(pHierProj)
16701717
VSConstants.S_OK
1718+
16711719
interface IVsUpdateSolutionEvents3with
16721720
memberx.OnBeforeActiveSolutionCfgChange(_oldCfg,_newCfg)=
1673-
queuedWork<- Some([])
1721+
// this will be called for each project, but wait dialogs cannot 'stack'
1722+
// i.e. if a wait dialog is already open, subsequent calls to StartWaitDialog
1723+
// will not override the current open dialog
1724+
waitDialog<-
1725+
{
1726+
WaitCaption= FSharpSR.GetString FSharpSR.ProductName
1727+
WaitMessage= FSharpSR.GetString FSharpSR.UpdatingSolutionConfiguration
1728+
ProgressText= None
1729+
StatusBmpAnim=null
1730+
StatusBarText= None
1731+
DelayToShowDialogSecs=1
1732+
IsCancelable=false
1733+
ShowMarqueeProgress=true
1734+
}
1735+
|> WaitDialog.start projNode.Site
1736+
|> Some
1737+
16741738
VSConstants.S_OK
1739+
16751740
memberx.OnAfterActiveSolutionCfgChange(_oldCfg,_newCfg)=
1676-
match queuedWorkwith
1677-
| Some(l)-> l|> List.iter(fun projNode-> projNode.ComputeSourcesAndFlags())
1741+
match waitDialogwith
1742+
| Some x->
1743+
x.Dispose()
1744+
waitDialog<- None
16781745
| None->()
1679-
queuedWork<- None
16801746
VSConstants.S_OK
1681-
1747+
1748+
interface IVsUpdateSolutionEvents4with
1749+
memberx.OnActiveProjectCfgChangeBatchBegin()=
1750+
batchState<- BatchWaiting
1751+
memberx.OnActiveProjectCfgChangeBatchEnd()=
1752+
batchState<- NonBatch
1753+
memberx.UpdateSolution_BeginFirstUpdateAction()=
1754+
()
1755+
memberx.UpdateSolution_BeginUpdateAction(_dwAction)=
1756+
()
1757+
memberx.UpdateSolution_EndLastUpdateAction()=
1758+
()
1759+
memberx.UpdateSolution_EndUpdateAction(_dwAction)=
1760+
()
1761+
memberx.UpdateSolution_QueryDelayFirstUpdateAction(_pfDelay)=
1762+
()
16821763

16831764
interface IVsTrackProjectRetargetingEventswith
16841765
overridethis.OnRetargetingBeforeChange

‎vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectPrelude.fs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
158158
[<Literal>]
159159
letOutputTypeDescription="OutputTypeDescription"
160160
[<Literal>]
161+
letProductName="ProductName"
162+
[<Literal>]
161163
letProject="Project"
162164
[<Literal>]
163165
letProjectFile="ProjectFile"
@@ -215,6 +217,10 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
215217
letAddReferenceAssemblyPageDialogNoItemsText="AddReferenceAssemblyPageDialogNoItemsText";
216218
[<Literal>]
217219
letFSharpCoreVersionIsNotLegacyCompatible="FSharpCoreVersionIsNotLegacyCompatible";
220+
[<Literal>]
221+
letComputingSourcesAndFlags="ComputingSourcesAndFlags"
222+
[<Literal>]
223+
letUpdatingSolutionConfiguration="UpdatingSolutionConfiguration"
218224

219225

220226
typeprivateTypeInThisAssembly=classend

‎vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
</EmbeddedResource>
5353
<CompileInclude="AssemblyInfo.fs" />
5454
<CompileInclude="ProjectPrelude.fs" />
55+
<CompileInclude="WaitDialog.fs" />
5556
<CompileInclude="MSBuildUtilities.fs" />
5657
<CompileInclude="AppConfigHelper.fs" />
5758
<CompileInclude="Project.fs" />

‎vsintegration/src/FSharp.ProjectSystem.FSharp/VSPackage.resx‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,13 @@
206206
<value>Build</value>
207207
</data>
208208
<dataname="1"xml:space="preserve">
209-
<value></value>
209+
<value />
210210
</data>
211211
<dataname="2"xml:space="preserve">
212-
<value></value>
212+
<value />
213213
</data>
214214
<dataname="3"xml:space="preserve">
215-
<value></value>
215+
<value />
216216
</data>
217217
<assemblyalias="System.Windows.Forms"name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
218218
<dataname="300"type="System.Resources.ResXFileRef, System.Windows.Forms">
@@ -517,11 +517,17 @@
517517
</data>
518518
<dataname="AddReferenceAssemblyPageDialogRetargetingText"xml:space="preserve">
519519
<value>The project will be retargeted, and its targeted frameworks will be reduced.</value>
520-
</data>
520+
</data>
521521
<dataname="AddReferenceAssemblyPageDialogNoItemsText"xml:space="preserve">
522522
<value>All of the Framework assemblies are already referenced. Please use the Object Browser to explore the references in the Framework.</value>
523523
</data>
524524
<dataname="FSharpCoreVersionIsNotLegacyCompatible"xml:space="preserve">
525525
<value>Referencing this version of FSharp.Core will cause your project to be incompatible with older versions of Visual Studio. Do you want to continue?</value>
526526
</data>
527-
</root>
527+
<dataname="ComputingSourcesAndFlags"xml:space="preserve">
528+
<value>Updating compilation sources and flags...</value>
529+
</data>
530+
<dataname="UpdatingSolutionConfiguration"xml:space="preserve">
531+
<value>Updating solution configuration...</value>
532+
</data>
533+
</root>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp