Ping/Start new computation of the next component (c#)

Hey,

I created a component, that needs to do some heavy computations. If the computation is done in the solve instance function the whole UI freeze and waits for it. That’s why I make the computation in an extra thread. That works fine for me, but the problem is after the computation finished and the new result is set to the output, the next component does not start a recomputation. Is there any command to start a new computation for the following components or do I need to all totally different. Below you can see my code.

Best Regards

public class SampleComponent : GH_Component
{
  public SampleComponent()
    : base("SampleComponent", "Nickname", "Description", "Category", "Subcategory")
  {  }

  protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
  {
    pManager.AddIntegerParameter("Number", "Number", "Number", GH_ParamAccess.item);
  }

  protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
  {
    pManager.AddIntegerParameter("Result", "Result", "Result", GH_ParamAccess.item);
  }

  protected override void SolveInstance(IGH_DataAccess DA)
  {
    int number = 0;
    if (!DA.GetData(0, ref number)) { return; }
    int res = 1;
    Task computingTask = new Task(() =>
    {
      for (int i = 0; i < number; i++)
      {
        res = res + res;
      }
      Params.Output[0].ClearData();
      DA.SetData(0, res);
      //Ping/Start new computation of the next component
    });
    computingTask.Start();
    DA.SetData(0, null);
  }

  protected override System.Drawing.Bitmap Icon
  { get { return null; } }

  public override Guid ComponentGuid
  {
    get { return new Guid("9a4e60bb-c6fc-47d7-acbe-698723e162a0"); }
  }
}

When your task completes, you must store the result locally somewhere, then schedule a new solution on the GH_Document which contains your component. This schedule will allow you to register a callback delegate, and in this delegate you expire your component causing it to recompute during the next solution. So your SolveInstance() method needs to be able to behave in two different ways. It must either start a computation or it must assign the result of a previously finished computation.

Thanks for your fast answer.

Ich changed the code to the one below and it works better. I’m still facing one problem, if I use more than one component, that does its computation in a different thread, the UI is just free for the first one.

1.     public class SampleComponent : GH_Component
2.     {
3.         public SampleComponent()
4.           : base("SampleComponent", "Nickname", "Description", "Category", "Subcategory")
5.         { }

6.         protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
7.         {
8.             pManager.AddIntegerParameter("Number", "Number", "Number", GH_ParamAccess.item);
9.         }

10.         protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
11.         {
12.             pManager.AddIntegerParameter("Result", "Result", "Result", GH_ParamAccess.item);
13.         }

14.         int res = 1;
15.         bool setSolution = false;
16.         Task computingTask = null;
17.         protected override void SolveInstance(IGH_DataAccess DA)
18.         {
19.             if (setSolution)
20.             {
21.                 Params.Output[0].ClearData();
22.                 DA.SetData(0, res);
23.                 setSolution = false;
24.                 return;
25.             }
26.             if (computingTask == null || computingTask.IsCompleted)
27.             {
28.                 int number = 0;
29.                 if (!DA.GetData(0, ref number)) { return; }
30.                 res = 1;
31.                 DA.SetData(0, null);
32.                 computingTask = new Task(() =>
33.                 {
34.                     for (int i = 0; i < number; i++)
35.                     {
36.                         res = res + res;
37.                     }
38.                 });
39.                 computingTask.ContinueWith(r =>
40.                 {
41.                     if (r.Status == TaskStatus.RanToCompletion)
42.                     {
43.                         setSolution = true;
44.                         ExpireSolution(false);
45.                         OnPingDocument().NewSolution(false);
46.                     }
47.                 },TaskScheduler.FromCurrentSynchronizationContext());
48.                 computingTask.Start();

49.             }
50.         }

51.         protected override System.Drawing.Bitmap Icon
52.         { get { return null; } }

53.         public override Guid ComponentGuid
54.         {
55.             get { return new Guid("9a4e60bb-c6fc-47d7-acbe-698723e162a0"); }
56.         }
57.     }

I solved the last problem by calling

OnPingDocument().ScheduleSolution(1);

instead of

1 Like