[IronPython] Question about Control.Invoke and CallTargets

Dino Viehland dinov at microsoft.com
Thu Nov 27 00:52:16 CET 2008

Does it also repro under a debugger?  Given it's a full 5 seconds could you pause the app when this is happening to see what the actual stacks are?

From: users-bounces at lists.ironpython.com [users-bounces at lists.ironpython.com] On Behalf Of Glenn Jones [glenn.k.jones+ipy at gmail.com]
Sent: Tuesday, November 25, 2008 10:40 AM
To: Curt Hagenlocher
Cc: Discussion of IronPython
Subject: Re: [IronPython] Question about Control.Invoke and CallTargets

We only see the long pause in IP2. To give a feeling of magnitude:

* The first recalc of Resolver (without user input) takes ~3500ms, almost the same as IP1
* The first recalc with user input that hits this issue takes ~5000ms
* Recalcs after that take ~400ms, which is on par with IP1

Interestingly, removing the form.Invoke and calling it directly (as a test), removed the pause from that place, but it introduced it at a later stage, where we ask our grid component to refresh itself, which probably uses a cross thread invocation itself.

CheckForIllegalCrossThreadCalls is turned off, but we enable it when running tests, so we know we don't actually do any (except that experiment above).

Glenn & Orestis

On Tue, Nov 25, 2008 at 3:57 PM, Curt Hagenlocher <curt at hagenlocher.org<mailto:curt at hagenlocher.org>> wrote:
Is this something that changed between 1.1 and 2.0 or do you see the same behavior in both?

On Tue, Nov 25, 2008 at 7:47 AM, Glenn Jones <glenn.k.jones+ipy at gmail.com<mailto:glenn.k.jones%2Bipy at gmail.com>> wrote:
Hello guys,

We're seeing some strange behaviour when doing cross-thread invoking in Resolver. Unfortunately, we can't get a minimal repro for this, so I'll just describe what's going on and hopefully something will be obvious.

We do our recalcs in a background thread, to avoid blocking the GUI. When a recalc finishes, it has to update the UI with the results of the calculations. We do that with:

    form.Invoke(self._synchroniseUI.Target, self, startedTime, aborted, state)

where 'form' is our main form, 'self' is a Document instance that holds the sub-engine and all the results, `startedTime` is a DateTime, `aborted` is a ManualResetEvent, and `state` is an object with some state extracted from the recalculations.

We have instrumented the execution of this, and we find this weird pattern: While _synchroniseUI takes say 500ms, form.Invoke takes 5000ms, but only the first time it's called. Subsequent updates behave normally. Our guess would be that some kind of overhead is created lazily once, and comes for free after that, but it's hard to see what's going on.

We've tried the same Invoke call with CallTarget0 and a lambda with the arguments and with CallTarget5 with the same results.

Is there something potentially expensive that involves CallTargets and cross-thread invocations? This was fine in IronPython 1.1.

Glenn & Orestis

Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20081126/93e94ab2/attachment.html>

More information about the Ironpython-users mailing list