我在名为TridentForm的表单上使用IronPython 2.6和WebbrowserControl。这用于显示报告等。
主窗体LaunchForm有一个具有OnClick事件处理程序的按钮。此事件处理程序设置了一些内容,然后启动BackgroundWorker。后台工作程序完成,并在此回调中实例化TridentForm,显示它等等。
现在这很好用,这是一个精简的当前代码:
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
如您所见,self.form_report(TridentForm)在首次创建后重复使用。这样做的原因是日志语句“Creating TridentForm”和“Getting TridentForm”之间的时间长达7秒(看似没什么)。日志不说谎。无论如何,我认为这是IE的ActvieX控件的组件初始化时间。
显然,我不想等待7秒钟。
所以,我决定尝试在runReport_handler结束时创建表单 - 它会让UI冻结一点,但后台线程正在运行,所以没什么大不了的。注意有关线程ID的日志记录 - 我已经确认在同一个线程上调用了runReport_handler和runReport_finished。
所以,我的问题:简单地将该创建移动到runReport_handler的末尾会给我一些有趣的未处理的线程异常:
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)
和
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)
两者都没有任何意义。作为奖励,现在点击主表单也会产生该消息。
提到例外:
无关控制的第33行:
def OnMouseUp(self,e): self.pressed =假 如果self.image_down: self.Invalidate() super(SimpleImageButton,self).OnMouseUp(e)#dies here。是的,这是Control的子类。
和TridentForm代码:
def TridentNavigating(self,sender,e): 如果e.Url!= self.dest_url和e.Url!= PLEASE_WAIT_URL:#dies here。 self是一个Form,我猜这是一个Control的子类。但是,这一行中的任何事情都没有触及clr类型 - self.dest_url是一个python属性
所以,我迷路了。
或者,如果你可以采用其他方式“预加载”TridentForm,那就太好了。谢谢。 e.Cancel = true
答案 0 :(得分:0)
呃,这是超级()电话......抱歉浪费每个人的时间:)。