Hi @DavidRutten et al,
I’m building a set of grasshopper components that update frequently from a background thread(s) and I am having some issues with
ScheduleSolution(int interval) in some scenarios.
In this reproduction I have a timer ticking at a given interval, which calls
ScheduleSolution and should expire the component and update the document in the near future. The component message displays the number of times we call
ScheduleSolution versus the number of times the delegate gets called, and the data record and panel show the total number of actual component updates (which should be less than the number of delegates called, since multiple may be called for one schedule).
This is the expected behaviour, where the number of callbacks is equal (or one or two ticks behind) the number of timer ticks:
However, when I switch documents (or create new) and return the solutions still get scheduled but the callbacks are never executed (Fig 2).
When the document is manually updated, the scheduled delegates do get updated (Fig 3) - so it seems like they are getting correctly added to the queue, but the document isn’t getting a new solution called on schedule.
Lastly, It seems like certain combinations (or perhaps timings?) of scheduling the solutions (Fig 4) can also cause this behavior, though less permanently and it is less reproducible than in the new document scenario (Fig 2).
My first thoughts were to do with concurrency - but using a lock on the scheduling does not appear to make any difference, and I would have expected this to be handled via the
BeginInvoke regardless. Inspecting the variables in VS shows that
m_scheduleDelegates does add the delegates to the list, it simply never recomputes the document. Recomputing the document manually (i.e. updating a slider, clicking a button, enabling a component) will execute the scheduled delegates.
Do you know why this may be the case? I don’t get any unexpected diagnostics from VS.
The same code does produce expected behavior with ExpireSolution(true) instead of
ScheduleSolution but of course this more or less freezes the UI indefinitely when the intervals are tight. This is the code.
Note: The goal here isn’t to replicate a timer component or complete a regularly scheduled execution (in which case scheduling a solution from the
SolveInstance might apply, but is instead to respond to events fired quickly from multiple external sources on separate threads.