views:

66

answers:

1

Hi,

I'm using IronPython 2.6 and a WebbrowserControl on a form called TridentForm. This is used for displaying reports, etc.

The main form, LaunchForm, has a button that has an OnClick event handler. This event handler sets some stuff up and then kicks off a BackgroundWorker. The Background worker completes, and in this callback it instantiates TridentForm, shows it, etc, etc.

Now This works fine, here's an abridged current code:

class LaunchForm(Form):
 def __init__(self):
            #blah blah, InitilizeComponents(), blah
  self.form_splash = None
  self.form_report = None

  self._report_worker = BackgroundWorker()
  self._report_worker.DoWork += self.runReport
  self._report_worker.RunWorkerCompleted += self.runReport_finished

 def runReport_handler(self, sender, args):
  self._report_worker.RunWorkerAsync(job_type)
  log.debug("renReport_handler called on thread %s"%(Thread.CurrentThread.ManagedThreadId))

 def runReport(self, sender, args): #run by a backgroundworker
  #do stuff, doesn't matter

 def runReport_finished(self, sender, args):
  #error checking, etc
  log.debug("reunReport_finished called on thread %s"%(Thread.CurrentThread.ManagedThreadId))

  if not self.form_report:
   log.debug("Creating TridentForm")
          self.form_report = TridentForm()
  log.debug("Getting TridentForm")
  vf = self.form_report

As you can see, self.form_report (TridentForm) is reused after it's first creation. The reason for this is that between the log statements "Creating TridentForm" and "Getting TridentForm" up to 7 seconds is spent doing (seemingly) nothing. The log tells no lies. Anyway, I assume that this is component init time for IE's ActvieX control.

Obviously, I don't want to be waiting 7 seconds on this.

So, I decided to try creating the form at the end of runReport_handler - it'll make the UI freeze a bit, but the background thread is working, so no biggie. Note the logging statements about the thread IDs - i've confirmed that both runReport_handler and runReport_finished get called on the same thread.

So, my problem: Simply moving that creation up to the end of runReport_handler gives me several fun unhandled thread exceptions:

Traceback (most recent call last):

  File "C:\completely\unrelated\control\subclass\used\on\the\mainform.py", line 33, in OnMouseUp

TypeError: cannot access protected member OnMouseUp without a python subclass of Control

Microsoft.Scripting.ArgumentTypeException: cannot access protected member OnMouseUp without a python subclass of Control

   at IronPython.Runtime.Types.BuiltinFunction.<>c__DisplayClass6.<MakeBuiltinFunctionDelegate>b__0(Object[] callArgs, Boolean& shouldOptimize)

   at IronPython.Runtime.Types.BuiltinFunction.BuiltinMethodCaller`2.Call1(CallSite site, CodeContext context, TFuncType func, T0 arg0)

   at Microsoft.Scripting.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)

   at Microsoft.Scripting.Interpreter.DynamicInstruction`4.Run(InterpretedFrame frame)

   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

   at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)

   at IronPython.Compiler.PythonCallTargets.OriginalCallTarget2(PythonFunction function, Object arg0, Object arg1)

   at IronPython.Runtime.PythonFunction.FunctionCaller`2.Call2(CallSite site, CodeContext context, Object func, T0 arg0, T1 arg1)

   at Microsoft.Scripting.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)

   at IronPython.Runtime.PythonFunction.FunctionCaller`2.Default1Call2(CallSite site, CodeContext context, Object func, T0 arg0, T1 arg1)

   at CallSite.Target(Closure , CallSite , CodeContext , Object , Object )

   at Microsoft.Scripting.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)

   at IronPython.NewTypes.System.Windows.Forms.Control_13$14.OnMouseUp(MouseEventArgs )

   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

   at System.Windows.Forms.Control.WndProc(Message& m)

   at IronPython.NewTypes.System.Windows.Forms.Control_13$14.WndProc(Message& )

   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

and

Traceback (most recent call last):

  File "C:\TridentForm.py", line 159, in TridentNavigating

TypeError: cannot access protected member OnMouseUp without a python subclass of Control

Microsoft.Scripting.ArgumentTypeException: cannot access protected member OnMouseUp without a python subclass of Control

   at IronPython.Runtime.Types.BuiltinFunction.<>c__DisplayClass6.<MakeBuiltinFunctionDelegate>b__0(Object[] callArgs, Boolean& shouldOptimize)

   at IronPython.Runtime.Types.BuiltinFunction.BuiltinMethodCaller`2.Call1(CallSite site, CodeContext context, TFuncType func, T0 arg0)

   at Microsoft.Scripting.Interpreter.DynamicInstruction`4.Run(InterpretedFrame frame)

   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

   at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)

   at IronPython.Runtime.PythonFunction.FunctionCaller`2.Call2(CallSite site, CodeContext context, Object func, T0 arg0, T1 arg1)

   at CallSite.Target(Closure , CallSite , CodeContext , Object , Object )

   at IronPython.NewTypes.System.Windows.Forms.Control_13$14.OnMouseUp(MouseEventArgs )

   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

   at System.Windows.Forms.Control.WndProc(Message& m)

   at IronPython.NewTypes.System.Windows.Forms.Control_13$14.WndProc(Message& )

   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Both of which don't make any sense. As a bonus, now clicking on the main form produces that message too.

The refered to exceptions:

line 33 of the unrelated control:

def OnMouseUp(self, e): self.pressed = False if self.image_down: self.Invalidate() super(SimpleImageButton, self).OnMouseUp(e) #dies here. Yes, this is a subclass of Control.

and the TridentForm code:

def TridentNavigating(self, sender, e): if e.Url != self.dest_url and e.Url != PLEASE_WAIT_URL: #dies here. self is a Form, which I guess is a subclass of Control. But still, none of the things in this line ever touch clr types - self.dest_url is a python attribute

So, I'm lost.

Alternatively, if you could sugegst a way to "preload" TridentForm some other way, that'd be great. Thanks. e.Cancel = true

A: 

Ugh, it was the super() call... Sorry for wasting everyone's time :)

NoName