How to create a new thread from inside Rhino/GH?

This is when the said process will invoke thread lock and respectively crash Rhino.

How can I avoid this crash?

UPDATE:
How would this:

using System.Threading;
new Thread(() => 
{
    Thread.CurrentThread.IsBackground = true; 
    /* run your code here */ 
    Console.WriteLine("Hello, world"); 
}).Start();

look like in IronPython? :thinking:
I’m particularly confused with the lambda operator there.

  private void RunScript(object x, object y, ref object A)
  {
    // Create new thread
    //Thread t1 = new Thread(ActionA); 

    // or with lambda
     Thread t1 = new Thread(() => ActionA());

    // Schedule execution
    t1.Start(); 
  }

  // <Custom additional code> 
 
  /// <summary>
  /// Do stuff
  /// </summary>
  /// <returns></returns>
  public  void ActionA() 
  { 
    for (int i= 0; i < 8; i++) 
      Print(i.ToString()); 
  }
  // </Custom additional code> 
}

// Output should be: 0,1,2,3,4,5,6,7

https://www.tutorialspoint.com/csharp/csharp_multithreading.htm

https://docs.microsoft.com/en-us/dotnet/standard/threading/

1 Like

Thanks @rawitscher-torres,

This is what worked from python.

from System.Threading import Thread, ParameterizedThreadStart

def prnt(o): # having a single argument is important, even if it's not used :D
    System.Console.WriteLine("Hello, world")
t = Thread(ParameterizedThreadStart(prnt))
t.Start()

Oh, Snap!
It still crashes Rhino.

Holy crap ):

I fixed it
It crashes cuz of Console.WriteLine()

if you put print() it works. I always forget that Rhino is not a console app.

Funny, in C# it wont crash, it just wont print anything. Perhaps its some freaky python thing that makes everything panic and want to run away

1 Like

Do you know how can I “extract” object’s values after executing the method in the new thread?

Do you have a code example? I wont be able to help you in Python though

from System.Threading import Thread, ParameterizedThreadStart

z = ""

def prnt(o): # having a single argument is important, even if it's not used :D
    print("Hello, world")
    global z
    z = "some value"
    #return "some value"

t = Thread(ParameterizedThreadStart(prnt))

t.Start()
print "z={}".format(z)

Should be straightforward understandble in c# (though I don’t speak csharp much :P)

Haha, print "z={}".format(sc.sticky['z']) is executed before the new thread that assigns the value.

I guess I have to use sticky

from System.Threading import Thread, ParameterizedThreadStart
import scriptcontext as sc

sc.sticky['z'] = ''

def prnt(o): # having a single argument is important, even if it's not used :D
    print("Hello, world")
    sc.sticky['z'] = "some value"
    #return "some value"

t = Thread(ParameterizedThreadStart(prnt))

t.Start()

for i in range(10):
    print(i)

print "z={}".format(sc.sticky['z'])

private void RunScript(object x, object y, ref object A)
  {
    Thread t1 = new Thread(() => ActionA());

    t1.Start(); 
    
    A = string.Format(" Z = {0}", z);
  }

  // <Custom additional code> 
  string z = "";
  
  public  void ActionA() 
  { 
    Print("Hello, world");   
    z = "some value";
  }
  // </Custom additional code> 
}

does this work?

Of course

image

Python seems to do some freaky stuff here… In C# that execution order does not happen. Perhaps the Python guys in the forum can be best of help here for you, since my python knowledge is not as good (plus I don’t like python so much lol…) @Helvetosaur maybe he is the guy, I would tag Dale as well, but I dont know if we should be bothering him with this.

Hit recompute

1 Like

unfortunately the original case still crashes Rhino.

I’ll now test creating an IronPython engine instance from within IronPython acting as a sub-thread. :smiley:

I’m pushing the limits of IronPython, just to avoid thinking in C# :stuck_out_tongue_winking_eye:

1 Like