From 7d77a393a60174a9009682ec89c5eb37560fa72b Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 1 Nov 2017 19:06:01 +0000 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Rework AsyncTask to use ConfigureAwait We should be using `ConfigureAwait(false)` for our `Task.Run` calls to ensure that the Continuations do NOT run on the main thread. This is probably the reason why VS locks up when we call these methods. The Continuation which calls `Complete` is trying to run on the UI thread, which will be locked waiting for the Task to complete. We should also provide the Cancelation Token and the TaskScheduler for the `Parallel.ForEach` calls. --- src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs | 7 ++++++- src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs | 5 +++-- src/Xamarin.Android.Build.Tasks/Tasks/Crunch.cs | 7 ++++++- .../Tasks/GetAdditionalResourcesFromAssemblies.cs | 10 ++++++---- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs index 3ff06581597..f7ebd479773 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs @@ -216,7 +216,12 @@ public override bool Execute () assemblyMap.Load (AssemblyIdentityMapFile); - ThreadingTasks.Parallel.ForEach (ManifestFiles, () => 0, DoExecute, (obj) => { Complete (); }); + ThreadingTasks.ParallelOptions options = new ThreadingTasks.ParallelOptions { + CancellationToken = Token, + TaskScheduler = ThreadingTasks.TaskScheduler.Current, + }; + + ThreadingTasks.Parallel.ForEach (ManifestFiles, options, () => 0, DoExecute, (obj) => { Complete (); }); base.Execute (); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs index ab901ceff2f..f0d19b65bc5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs @@ -239,11 +239,11 @@ bool DoExecute () { var task = ThreadingTasks.Task.Run ( () => { return RunParallelAotCompiler (nativeLibs); - }); + }, Token); task.ContinueWith ( (t) => { Complete (); - }); + }).ConfigureAwait (false); base.Execute (); @@ -267,6 +267,7 @@ bool RunParallelAotCompiler (List nativeLibs) ThreadingTasks.ParallelOptions options = new ThreadingTasks.ParallelOptions { CancellationToken = cts.Token, + TaskScheduler = ThreadingTasks.TaskScheduler.Current, }; ThreadingTasks.Parallel.ForEach (GetAotConfigs (), options, diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Crunch.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Crunch.cs index 47a41126fac..5b4d62c80c5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Crunch.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Crunch.cs @@ -80,9 +80,14 @@ public override bool Execute () if (!imageFiles.Any ()) return true; + ThreadingTasks.ParallelOptions options = new ThreadingTasks.ParallelOptions { + CancellationToken = Token, + TaskScheduler = ThreadingTasks.TaskScheduler.Current, + }; + var imageGroups = imageFiles.GroupBy (x => Path.GetDirectoryName (Path.GetFullPath (x.ItemSpec))); - ThreadingTasks.Parallel.ForEach (imageGroups, () => 0, DoExecute, (obj) => { Complete (); }); + ThreadingTasks.Parallel.ForEach (imageGroups, options, () => 0, DoExecute, (obj) => { Complete (); }); return !Log.HasLoggedErrors; } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs index 8c529f8b35b..7d3d4cd83a4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs @@ -427,11 +427,13 @@ public override bool Execute () } } } - }).ContinueWith ((t) => { - if (t.Exception != null) - Log.LogErrorFromException (t.Exception.GetBaseException ()); + }, Token).ContinueWith ((t) => { + if (t.Exception != null) { + var ex = t.Exception.GetBaseException (); + LogError (ex.Message + Environment.NewLine + ex.StackTrace); + } Complete (); - }); + }).ConfigureAwait (false); var result = base.Execute ();