[IronPython] System.Windows.Forms.MethodInvoker

Dino Viehland dinov at exchange.microsoft.com
Wed May 14 18:15:35 CEST 2008


Ok I took a look at this and I believe this is a CLR bug - windbg was really just useful for showing the exception which VS wasn't doing for me.  I've included the simple repro below which doesn't require IronPython.  The issue is that when we have a dynamic method closed over the 1st parameter the remoting stack thinks we have the wrong number of arguments.  It then dutifily tries to report an error but it AVs because the method has no declaring type because it's a dynamic method!  So it's a bit of a double bug.  There's also the fact that the process isn't getting ripped when this happens so someone's probably swallowing an exception they're not supposed to - a triple bug!

I've sent this off to the CLR team to have them take a look.  Unless they have a clever workaround this like means it won't work until the CLR is fixed :(.

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Globalization;

class Test {

    delegate void MyDelegate();

    public static void Main(string[]args) {
        DynamicMethod test = new DynamicMethod("Hello",
            typeof(void),
            new Type[]{typeof(string)},
            typeof(string).Module);

        MethodInfo writeString = typeof(Console).GetMethod("WriteLine",
            new Type[]{typeof(string)});

        ILGenerator il = test.GetILGenerator(256);
        il.Emit(OpCodes.Ldarg_0);
        il.EmitCall(OpCodes.Call, writeString, null);
        il.Emit(OpCodes.Ret);

        MyDelegate dlg =  (MyDelegate) test.CreateDelegate(typeof(MyDelegate), "Hello World!");
        dlg.BeginInvoke(new AsyncCallback(Finished), null);
        Console.ReadLine();
    }

    public static void Finished(IAsyncResult ar) {
    }
}



From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Matthew Barnard
Sent: Wednesday, May 14, 2008 1:01 AM
To: Discussion of IronPython
Subject: Re: [IronPython] System.Windows.Forms.MethodInvoker

I spent a good amount of time prodding like an awkward schoolboy at the framework with windbg.
Everything is fine from the point of the BeginInvoke thread is created to the point where the function is being looked up.
The framework spends a good deal of time rooting around in a MethodTable and looks up and calls a constructor for whatever it found there.
This was the last thing I saw it doing before raising an Access Violation, though I was looking at the TV whilst stepping so I'm sure I missed something critical.
And now I can sleep.

On Tue, May 13, 2008 at 8:41 PM, Matthew Barnard <m.stephen.barnard at gmail.com<mailto:m.stephen.barnard at gmail.com>> wrote:
Ah- good catch Dino. Didn't see a "Started," so I failed to notice the "Finished." was actually printing ;)
It appears that, as with the bit of code that provoked this test, start() is not being executed by BeginInvoke.
Thread.Sleep(20000) still drops to "Finished" as soon as the script starts.

And my assembly skills are nonexistant; you're on your own with windbg.

On Tue, May 13, 2008 at 7:05 PM, Dino Viehland <dinov at exchange.microsoft.com<mailto:dinov at exchange.microsoft.com>> wrote:

Where'd the call to Console.ReadLine go?  That's the reason you don't see Finished printing...  On 1.1 and 2.0B2 from the console or in a file w/ a call to Console.ReadLine or raw_input I end up seeing finished getting printed.  We're simply exiting before the asynchronous operation but that doesn't fully answer the question - started is still never printing!  Stranger yet you can call mi() directly showing the delegate is clearly created correctly and working.  Anyway, I'll have to look at it closer - it might require windbg to figure out what's going wrong here.



From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com>] On Behalf Of Matthew Barnard
Sent: Tuesday, May 13, 2008 5:39 PM
To: IronPython List
Subject: [IronPython] System.Windows.Forms.MethodInvoker



The C# sample runs as expected, displaying 'Started. Finished.', but the ipy does nothing.
Can someone enlighten me as to the difference? I assume it is something to do with the way functions are represented in ipy vs. what methodinvoker is looking for,
but I'm honestly lost.

C#:

class foo
    {
        public void start()
        {
            Console.WriteLine("Started.");
            Thread.Sleep(2000);
        }

        public void finish(IAsyncResult r)
        {
            Console.WriteLine("Finished.");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            foo bar = new foo();

            MethodInvoker mi = new MethodInvoker(bar.start);
            mi.BeginInvoke(new AsyncCallback(bar.finish), null);

            Console.ReadLine();
        }
    }


IPY:

import clr

clr.AddReferenceByPartialName('System.Windows.Forms')

from System import AsyncCallback
from System.Threading import Thread
from System.Windows.Forms import MethodInvoker

class foo:
    def start(self):
        print 'Started.'
        Thread.Sleep(2000)

    def finish(self, r):
        print 'Finished.'

bar = foo()
mi = MethodInvoker(bar.start)
mi.BeginInvoke(AsyncCallback(bar.finish), None)


___________________________
Matthew Barnard

_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



--
___________________________
Matthew Barnard



--
___________________________
Matthew Barnard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20080514/05fa9808/attachment.html>


More information about the Ironpython-users mailing list