Requesting new solutions from non-grasshopper threads - Grasshopper2024-03-29T02:11:24Zhttps://www.grasshopper3d.com/forum/topics/requesting-new-solutions-from-non-grasshopper-threads?commentId=2985220%3AComment%3A1222963&feed=yes&xn_auth=noGood to know, thanks for the…tag:www.grasshopper3d.com,2015-02-12:2985220:Comment:12228582015-02-12T00:21:14.156ZArendhttps://www.grasshopper3d.com/profile/Arend
<p>Good to know, thanks for the heads up. I'm still a bit puzzled when would be a good use case to use Invoke? Is code running in a grasshopper solution for example in a different thread than the UI thread?</p>
<p>Good to know, thanks for the heads up. I'm still a bit puzzled when would be a good use case to use Invoke? Is code running in a grasshopper solution for example in a different thread than the UI thread?</p> Oh incidentally if you're cal…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12229632015-02-11T23:01:41.126ZDavid Ruttenhttps://www.grasshopper3d.com/profile/DavidRutten
<p>Oh incidentally if you're calling methods from a thread that isn't the UI thread, you may have to invoke them properly. Normally you invoke a method on the UI thread by calling the <a href="https://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke%28v=vs.110%29.aspx" target="_blank">Invoke method</a> on a control or form. We've also put an <a href="http://4.rhino3d.com/5/rhinocommon/html/M_Rhino_RhinoWindow_Invoke.htm" target="_blank">Invoke method in RhinoCommon</a> to…</p>
<p>Oh incidentally if you're calling methods from a thread that isn't the UI thread, you may have to invoke them properly. Normally you invoke a method on the UI thread by calling the <a href="https://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke%28v=vs.110%29.aspx" target="_blank">Invoke method</a> on a control or form. We've also put an <a href="http://4.rhino3d.com/5/rhinocommon/html/M_Rhino_RhinoWindow_Invoke.htm" target="_blank">Invoke method in RhinoCommon</a> to make things easier.</p> Ok, it could be that my mista…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12227822015-02-11T22:08:10.931ZArendhttps://www.grasshopper3d.com/profile/Arend
<p>Ok, it could be that my mistakes are limited to #2. I'll have a good use case on friday to test it. (A controller that send out events every x miliseconds). I was not sure how expensive the ExpireSolution(false) call would be.</p>
<p>[Edit] My main line of though was: I don't trust the speed at which the controllers events (and thus requests for a new solution) are coming in. Nor will I know how fast or slow the entire solution will be. If e.g. 1000 requests for a new solution arrive in the…</p>
<p>Ok, it could be that my mistakes are limited to #2. I'll have a good use case on friday to test it. (A controller that send out events every x miliseconds). I was not sure how expensive the ExpireSolution(false) call would be.</p>
<p>[Edit] My main line of though was: I don't trust the speed at which the controllers events (and thus requests for a new solution) are coming in. Nor will I know how fast or slow the entire solution will be. If e.g. 1000 requests for a new solution arrive in the time that it takes grasshopper to calculate one solution; I wouldn't want 1000 callbacks to be executed. Hence the boolean check to only add one callback to expire the component.</p>
<p>On an related note: Is it possible that ScheduleSolution(0, callback) in a loop will crash rhino in a die-hard fashion? (For a test case: change the timeout on line 129 in the C# component in the attached file.)</p> Do you really need the privat…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12229482015-02-11T21:17:35.109ZDavid Ruttenhttps://www.grasshopper3d.com/profile/DavidRutten
<p>Do you really need the private bool there? As long as you don't trigger new solution from your callback, it should be fine. Even if you end up having multiple callbacks it shouldn't matter, as ExpireSolution(false) only does something the first time. The second time you call it the object is already expired and nothing happens. It takes a successful solution to make the object expirable again.</p>
<p>Do you really need the private bool there? As long as you don't trigger new solution from your callback, it should be fine. Even if you end up having multiple callbacks it shouldn't matter, as ExpireSolution(false) only does something the first time. The second time you call it the object is already expired and nothing happens. It takes a successful solution to make the object expirable again.</p> Yes.tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12226652015-02-11T21:15:09.220ZDavid Ruttenhttps://www.grasshopper3d.com/profile/DavidRutten
<p>Yes.</p>
<p>Yes.</p> Ok, small follow up of lesson…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12224762015-02-11T15:08:59.078ZArendhttps://www.grasshopper3d.com/profile/Arend
<p>Ok, small follow up of lessons learned:</p>
<p>Mistake #1:</p>
<p>Not treating Schedule Solution as an event. During the solution I called Schedule solution multiple times for the same component. This seemed to cause the lock-up scenario's.</p>
<p>Mistake #2:</p>
<p>Calling ExpireSolution(true) inside the callback of schedule solution, this seems a recipie for instant lock-up scenario's.</p>
<p></p>
<p>This seems to work pretty well:</p>
<p></p>
<p> private bool…</p>
<p>Ok, small follow up of lessons learned:</p>
<p>Mistake #1:</p>
<p>Not treating Schedule Solution as an event. During the solution I called Schedule solution multiple times for the same component. This seemed to cause the lock-up scenario's.</p>
<p>Mistake #2:</p>
<p>Calling ExpireSolution(true) inside the callback of schedule solution, this seems a recipie for instant lock-up scenario's.</p>
<p></p>
<p>This seems to work pretty well:</p>
<p></p>
<p> private bool _askingNewSolution;</p>
<p> public void ScheduleSolution(int miliseconds)<br/> {<br/> // only ask once.<br/> if (_askingNewSolution)<br/> {<br/> return;<br/> }<br/> _askingNewSolution = true;<br/> OnPingDocument().ScheduleSolution(10, doc =><br/> {<br/> ExpireSolution(false);<br/> _askingNewSolution = false;<br/> });<br/> }</p>
<p></p>
<p>Thanks a lot for the insight in solving this!</p> Hi david,
I'll give Schedule…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12223562015-02-11T14:21:12.042ZArendhttps://www.grasshopper3d.com/profile/Arend
<p>Hi david,</p>
<p></p>
<p>I'll give ScheduleSolution another try, and figure out why it did not work before; it seems to be a rather complete solution to my questions (thanks!). Am I correct in assuming that GH_Document.NewSolution() will be called after the Schedule solution executed all callbacks?</p>
<p>Thanks a lot for the explanation!</p>
<p>Hi david,</p>
<p></p>
<p>I'll give ScheduleSolution another try, and figure out why it did not work before; it seems to be a rather complete solution to my questions (thanks!). Am I correct in assuming that GH_Document.NewSolution() will be called after the Schedule solution executed all callbacks?</p>
<p>Thanks a lot for the explanation!</p> Any thoughts on a generic way…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12223502015-02-11T14:08:26.250ZDavid Ruttenhttps://www.grasshopper3d.com/profile/DavidRutten
<blockquote><span style="font-size: 13px;">Any thoughts on a generic way to solve this (Rather than each component subscribing to events, a way to subscribe to an expiration at the next earliest conveinience?)</span></blockquote>
<p></p>
<p><span style="font-size: 13px;">I need to think about this some more...</span></p>
<blockquote><span style="font-size: 13px;">Any thoughts on a generic way to solve this (Rather than each component subscribing to events, a way to subscribe to an expiration at the next earliest conveinience?)</span></blockquote>
<p></p>
<p><span style="font-size: 13px;">I need to think about this some more...</span></p> How do I determine if it's sa…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12224722015-02-11T14:06:58.888ZDavid Ruttenhttps://www.grasshopper3d.com/profile/DavidRutten
<blockquote><span style="font-size: 13px;">How do I determine if it's safe to request a new solution?</span></blockquote>
<p></p>
<p><span style="font-size: 13px;">If it's scheduling, it's always safe.</span></p>
<p></p>
<p><span style="font-size: 13px;">If you're going to call GH_Document.NewSolution(bool) yourself, or ExpireSolution(bool) on any object in the document, then you need to check the GH_Document.SolutionState. If it's GH_ProcessStep.Process, then you are not allowed to start new…</span></p>
<blockquote><span style="font-size: 13px;">How do I determine if it's safe to request a new solution?</span></blockquote>
<p></p>
<p><span style="font-size: 13px;">If it's scheduling, it's always safe.</span></p>
<p></p>
<p><span style="font-size: 13px;">If you're going to call GH_Document.NewSolution(bool) yourself, or ExpireSolution(bool) on any object in the document, then you need to check the GH_Document.SolutionState. If it's GH_ProcessStep.Process, then you are not allowed to start new solution.</span></p> What is the difference betwe…tag:www.grasshopper3d.com,2015-02-11:2985220:Comment:12224712015-02-11T14:03:26.661ZDavid Ruttenhttps://www.grasshopper3d.com/profile/DavidRutten
<blockquote><ol>
<li><p>What is the difference between ExpireSolution(true) and ExpireSolution(false)? When is it safe to call either of them?</p>
</li>
</ol>
</blockquote>
<p></p>
<p>ExpireSolution expires the object it is called on, including all dependent objects. If the argument is false, there will not be a new solution right after the expiration. If the argument is true, there will be a new solution right away.</p>
<p></p>
<p>Basically, use ExpireSolution(false) if you intend to do more…</p>
<blockquote><ol>
<li><p>What is the difference between ExpireSolution(true) and ExpireSolution(false)? When is it safe to call either of them?</p>
</li>
</ol>
</blockquote>
<p></p>
<p>ExpireSolution expires the object it is called on, including all dependent objects. If the argument is false, there will not be a new solution right after the expiration. If the argument is true, there will be a new solution right away.</p>
<p></p>
<p>Basically, use ExpireSolution(false) if you intend to do more stuff before the next solution starts. So if you want to expire 12 components, you call ExpireSolution(false); on them all, then when you're done you call GH_Document.NewSolution(false);</p>