From 59f87b2a7df2376af4ba83db76516ac5e8e65ba3 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Sat, 3 Apr 2021 17:56:39 +0100 Subject: [PATCH 1/4] feat(cancellation): exposes cancellation request (example in prime calculator) --- .../GH_AsyncComponent.cs | 21 ++++++++++++++++++- .../GrasshopperAsyncComponent.csproj | 2 +- .../Sample_PrimeCalculatorAsyncComponent.cs | 10 +++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/GrasshopperAsyncComponent/GH_AsyncComponent.cs b/GrasshopperAsyncComponent/GH_AsyncComponent.cs index 33179f9..3178cd3 100755 --- a/GrasshopperAsyncComponent/GH_AsyncComponent.cs +++ b/GrasshopperAsyncComponent/GH_AsyncComponent.cs @@ -88,7 +88,7 @@ namespace GrasshopperAsyncComponent public virtual void DisplayProgress(object sender, System.Timers.ElapsedEventArgs e) { - if (Workers.Count == 0) + if (Workers.Count == 0 || ProgressReports.Values.Count == 0) { return; } @@ -226,5 +226,24 @@ namespace GrasshopperAsyncComponent Message = "Done"; OnDisplayExpired(true); } + + public void RequestCancellation() + { + foreach (var source in CancellationSources) + { + source.Cancel(); + } + + CancellationSources.Clear(); + Workers.Clear(); + ProgressReports.Clear(); + Tasks.Clear(); + + Interlocked.Exchange(ref State, 0); + Interlocked.Exchange(ref SetData, 0); + Message = "Cancelled"; + OnDisplayExpired(true); + } + } } diff --git a/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj b/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj index 8a8db8d..c48c592 100755 --- a/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj +++ b/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj @@ -4,7 +4,7 @@ Debug AnyCPU - {695D2B91-DDB6-416E-8A99-DDE6253DA7AA} + {114D5E49-AC13-47F7-A70E-B4289579F4E3} Library Properties GrasshopperAsyncComponent diff --git a/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs b/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs index 0cd09e1..22b4e0b 100755 --- a/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs +++ b/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using GrasshopperAsyncComponent; +using System.Windows.Forms; namespace GrasshopperAsyncComponentDemo.SampleImplementations { @@ -32,6 +33,15 @@ namespace GrasshopperAsyncComponentDemo.SampleImplementations pManager.AddNumberParameter("Output", "O", "The n-th prime number.", GH_ParamAccess.item); } + + public override void AppendAdditionalMenuItems(ToolStripDropDown menu) + { + base.AppendAdditionalMenuItems(menu); + Menu_AppendItem(menu, "Cancel", (s, e) => + { + RequestCancellation(); + }); + } } public class PrimeCalculatorWorker : WorkerInstance From bdc105fa95ee861e9e1f342a70d229cfd3b5618a Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Sat, 3 Apr 2021 17:59:58 +0100 Subject: [PATCH 2/4] feat(cancellation): implements it cyclotron component --- .../Sample_UslessCyclesComponent.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_UslessCyclesComponent.cs b/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_UslessCyclesComponent.cs index b204825..b0027f8 100755 --- a/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_UslessCyclesComponent.cs +++ b/GrasshopperAsyncComponentDemo/SampleImplementations/Sample_UslessCyclesComponent.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using GrasshopperAsyncComponent; +using System.Windows.Forms; namespace GrasshopperAsyncComponentDemo.SampleImplementations { @@ -31,6 +32,15 @@ namespace GrasshopperAsyncComponentDemo.SampleImplementations { pManager.AddTextParameter("Output", "O", "Nothing really interesting.", GH_ParamAccess.item); } + + public override void AppendAdditionalMenuItems(ToolStripDropDown menu) + { + base.AppendAdditionalMenuItems(menu); + Menu_AppendItem(menu, "Cancel", (s, e) => + { + RequestCancellation(); + }); + } } public class UselessCyclesWorker : WorkerInstance From b93aa1a76a18afc59cc016d8b0f3471c252e12b7 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Sat, 3 Apr 2021 18:03:30 +0100 Subject: [PATCH 3/4] feat(cancellation): adds readme example --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 28a42c8..4ddcb87 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,26 @@ Q: Does this component use all my cores? A: OH YES. It goes WROOOM. ![image](https://user-images.githubusercontent.com/7696515/95597125-29310900-0a46-11eb-99ce-663b34506a7a.png) + +Q: Can I enable cancellation of a longer running task? + +A: Yes, now you can! In your component, just add a right click menu action like so: + +```cs + + public override void AppendAdditionalMenuItems(ToolStripDropDown menu) + { + base.AppendAdditionalMenuItems(menu); + Menu_AppendItem(menu, "Cancel", (s, e) => + { + RequestCancellation(); + }); + } + +``` + + + ### Debugging Quite easy: From 65fab580067ae82141ac980eee8985e05970f105 Mon Sep 17 00:00:00 2001 From: Dimitrie Stefanescu Date: Sat, 3 Apr 2021 18:04:53 +0100 Subject: [PATCH 4/4] feat: thread safety --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4ddcb87..1ac1cc4 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Looks nice, doesn't it? Notice that the solution runs "eagerly" - every time the - **Grasshopper and Rhino are still responsive!** - **There's progress reporting!** (personally I hate waiting for Gh to unfreeze...). +- **Thread safe**: 99% of the times this won't explode in your face. It still might though! ### Approach