How to refresh “Message” in a new thread?

I’ve written a program for a custom component ,there is code in breif:

protected override void SolveInstance(IGH_DataAccess DA)
{
     ........;
     Thread t=new Thread(MathCalculation);
     t.Start();
     ........;
}
private void MathCalculation()
{
     //this program may need 30 seconds
     .....^%^&*&%$$........;
     ......@#$%$#@.....;
     .......&^%%^&*......;

     Message="Calculation Finished!"
}

but when i run the component in grasshopper,after 30 seconds,the compnent can not show"Calculation Finished!" in the bottom,only if when i click the canvas or component or zoom in/out the canvas,the bottom can show “Calculation Finished!”…this is not I want,I need to
show the “Calculation Finished!” immediately without other canvas click…
Do you have some idea,Thank you very much!
image

It seems you are not setting the Message="..." in the main (UI) thread. I would move that line to the main thread (the SolveInstance() method, after awaiting the thread to finnish).

// Rolf

protected override void SolveInstance(IGH_DataAccess DA)
{
Message=“Hello”;
…;
Thread t=new Thread(MathCalculation);
t.Start();
…;
}
@RIL,thankyou ,i try ,but no work seems…

Hm. Now I see. Try this:

  private void RunScript(...)
  {
    m_done = !m_done;
    if (m_done) 
    {
      // due to expiring the solution (far below), this will exit and 
      // thus prevent the solution from running the threaded code 
      // over and over again in an infinite loop
      return; 
    }
    
    // prepare the job to be done
    var thread = new Thread(() => 
    {
      Thread.CurrentThread.IsBackground = true;       
      Component.Message = "Thread Is Running";      
      Thread.Sleep(1000);      // The "job"
      // Rig the component to run the "late message" in a separate 
      // re-run of the component
      var call_later = new GH_Document.GH_ScheduleDelegate(MessageToBeSentLater);
      GrasshopperDocument.ScheduleSolution(1, call_later);      
    });    
    thread.Start(); // run the thread    
  }
// <Custom additional code> 
  bool m_done = true;

  private void MessageToBeSentLater(GH_Document gh)
  {
    Component.Message = "Thread Is Done"; // Now the message will come across
    Component.ExpireSolution(false);
  }  
// </Custom additional code> 

// Rolf

2 Likes

The Message field is just a get/set property, setting it doesn’t update the ui. You can set it whenever you want, thread doesn’t matter, but you will have to expire the attribute layout before seeing a difference. THIS must happen on the UI thread. It happens automatically if the component is recalculated though.

1 Like

@RIL
Thank you Rolf
the method can work!amazing!
i see you use ExpireSolution(bool ) ,why you use bool=false?and why not use ExpirePreview(i tried,it also work…)
thank you very much again for the amazing code!

Thank you David,i understand.