Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortherzok <marius.ungureanu@xamarin.com>2019-12-02 16:37:15 +0300
committermonojenkins <jo.shields+jenkins@xamarin.com>2019-12-03 11:54:19 +0300
commitb1006fae4280dcbd0a902932d36554e76e178adb (patch)
tree5d60df88e0518decb9a15d19e85d045ce09332be
parentb505bbce1efd1d926c0b24c78fdd1b464815f84e (diff)
Try a different fix
Synchronously run the OnInitialize of the service to load the addin assemblies on the UI thread, then dispatch the actual composing to a background task. This should prevent deadlock issues, and ensure that the first init is called on the UI thread
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs73
1 files changed, 33 insertions, 40 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs
index 838daf1378..2cc3ca4b88 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Composition/CompositionManager.cs
@@ -56,23 +56,12 @@ namespace MonoDevelop.Ide.Composition
new AttributedPartDiscoveryV1 (StandardResolver),
new AttributedPartDiscovery (StandardResolver, true));
- static Action HandleMefQueriedBeforeCompletion = UninitializedThrowException;
-
- static void UninitializedLogWarning ()
- => LoggingService.LogWarning ("UI thread queried MEF while it was still being built:{0}{1}", Environment.NewLine, Environment.StackTrace);
-
- static void UninitializedThrowException ()
- => throw new InvalidOperationException ("MEF queried while it was still being built");
-
- static void ConfigureUninitializedMefHandling (bool throwException)
- => HandleMefQueriedBeforeCompletion = throwException ? new Action (UninitializedThrowException) : new Action (UninitializedLogWarning);
-
public static CompositionManager Instance {
get {
if (instance == null) {
var task = Runtime.GetService<CompositionManager> ();
- if (!task.IsCompleted && Runtime.IsMainThread) {
- HandleMefQueriedBeforeCompletion ();
+ if (!task.IsCompleted) {
+ LoggingService.LogWarning ("UI thread queried MEF while it was still being built:{0}{1}", Environment.NewLine, Environment.StackTrace);
}
instance = task.WaitAndGetResult ();
}
@@ -83,7 +72,19 @@ namespace MonoDevelop.Ide.Composition
protected override Task OnInitialize (ServiceProvider serviceProvider)
{
- return Task.Run (async () => await InitializeInstanceAsync ());
+ Runtime.AssertMainThread ();
+
+ var timings = new Dictionary<string, long> ();
+ var metadata = new CompositionLoadMetadata (timings);
+
+ var timer = Counters.CompositionLoad.BeginTiming (metadata);
+ var stepTimer = System.Diagnostics.Stopwatch.StartNew ();
+
+ var mefAssemblies = ReadAssembliesFromAddins (timer);
+
+ timings ["ReadFromAddins"] = stepTimer.ElapsedMilliseconds;
+
+ return Task.Run (() => InitializeInstanceAsync (timer, mefAssemblies));
}
/// <summary>
@@ -115,50 +116,42 @@ namespace MonoDevelop.Ide.Composition
{
}
- async Task InitializeInstanceAsync ()
+ async Task InitializeInstanceAsync (ITimeTracker<CompositionLoadMetadata> timer, HashSet<Assembly> mefAssemblies)
{
- var timings = new Dictionary<string, long> ();
- var metadata = new CompositionLoadMetadata (timings);
-
- using (var timer = Counters.CompositionLoad.BeginTiming (metadata)) {
- var fullTimer = System.Diagnostics.Stopwatch.StartNew ();
- var stepTimer = System.Diagnostics.Stopwatch.StartNew ();
-
- var mefAssemblies = await Runtime.RunInMainThread (() => ReadAssembliesFromAddins (timer));
- ConfigureUninitializedMefHandling (throwException: false);
- timings ["ReadFromAddins"] = stepTimer.ElapsedMilliseconds;
- stepTimer.Restart ();
-
- var caching = new Caching (mefAssemblies, new IdeRuntimeCompositionExceptionHandler ());
+ var metadata = timer.Metadata;
+ var fullTimer = System.Diagnostics.Stopwatch.StartNew ();
+ var stepTimer = System.Diagnostics.Stopwatch.StartNew ();
- // Try to use cached MEF data
+ var caching = new Caching (mefAssemblies, new IdeRuntimeCompositionExceptionHandler ());
+ // Try to use cached MEF data
+ using (timer) {
var canUse = metadata.ValidCache = caching.CanUse ();
- if (canUse) {
+ if (canUse) {
LoggingService.LogInfo ("Creating MEF composition from cache");
RuntimeComposition = await TryCreateRuntimeCompositionFromCache (caching);
- }
- timings ["LoadFromCache"] = stepTimer.ElapsedMilliseconds;
+ }
+ metadata.Timings ["LoadFromCache"] = stepTimer.ElapsedMilliseconds;
stepTimer.Restart ();
// Otherwise fallback to runtime discovery.
- if (RuntimeComposition == null) {
+ if (RuntimeComposition == null) {
LoggingService.LogInfo ("Creating MEF composition from runtime");
- var (runtimeComposition, catalog) = await CreateRuntimeCompositionFromDiscovery (caching, timer);
+ var (runtimeComposition, catalog) = await CreateRuntimeCompositionFromDiscovery (caching, timer);
RuntimeComposition = runtimeComposition;
CachedComposition cacheManager = new CachedComposition ();
caching.Write (RuntimeComposition, catalog, cacheManager).Ignore ();
- }
- timings ["LoadRuntimeComposition"] = stepTimer.ElapsedMilliseconds;
- stepTimer.Restart ();
+ }
+ metadata.Timings ["LoadRuntimeComposition"] = stepTimer.ElapsedMilliseconds;
+ stepTimer.Restart ();
ExportProviderFactory = RuntimeComposition.CreateExportProviderFactory ();
ExportProvider = ExportProviderFactory.CreateExportProvider ();
HostServices = Microsoft.VisualStudio.LanguageServices.VisualStudioMefHostServices.Create (ExportProvider);
-
- timings ["CreateServices"] = stepTimer.ElapsedMilliseconds;
- metadata.Duration = fullTimer.ElapsedMilliseconds;
+
+ metadata.Timings ["CreateServices"] = stepTimer.ElapsedMilliseconds;
+ metadata.Duration = fullTimer.ElapsedMilliseconds;
}
}