Python for .NET在调用System.Windows.Forms.Form构造函数时无声地失败

时间:2013-03-22 05:25:09

标签: c# python .net python.net

C#代码

我将以下 C#代码编译到名为“ MinimalFormsApp.dll ”的库中

using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsTest
{
    public static class CreateACoolWindow
    {
        public static void Main(string[] args)
        {
            CreateWindow();
        }

        public static void CreateWindow()
        {
            Thread winFormsThread = new Thread(new ThreadStart(StartFormApplication));
            winFormsThread.SetApartmentState(ApartmentState.STA);
            winFormsThread.Start();
            Console.WriteLine("Started thread");
        }

        private static void StartFormApplication()
        {
            Application.EnableVisualStyles();
            Console.WriteLine("EnableVisualStyles");
            Application.SetCompatibleTextRenderingDefault(false);
            Console.WriteLine("SetCompatibleTextRenderingDefault");
            FormSubClass dmw = new FormSubClass();
            Console.WriteLine("Created window object");
            Application.Run(dmw);
        }
    }

    public class FormSubClass : Form
    {
        public FormSubClass()
        {
            Console.WriteLine("FormSubClass Constructor called");
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            Console.WriteLine("Starting component init......");
            this.SuspendLayout();
            this.AutoScaleDimensions = new SizeF(6F, 13F);
            this.AutoScaleMode = AutoScaleMode.Font;
            this.ClientSize = new Size(300, 500);
            this.Name = "FormSubClass";
            this.Text = "FormSubClass";
            this.ResumeLayout(false);
            this.PerformLayout();

        }
    }
}

Python代码

使用 Python for .NET 和Python 2.7 for x86我尝试从这个C#库调用CreateWindow()方法。

我的python代码如下:

import clr
clr.AddReference("MinimalFormsApp")

from WindowsFormsTest import CreateACoolWindow
CreateACoolWindow.CreateWindow()

#Print some output
print "Mary had a little lamb,"
print "it's fleece was white as snow;"
print "and everywhere that Mary went",
print "her lamb was sure to go."

控制台输出

这就是Python在控制台打印出来的内容

  

启动线程
     玛丽有一只小羊羔,EnableVisualStyles
     SetCompatibleTextRenderingDefault

     

它的羊毛像雪一样白;      玛丽去羔羊的地方一定会去      FormSubClass构造函数名为

可以看出,它不会打印“Starting component init ......”并且它不会打印“Created window object”并且实际上没有创建Window。 Python程序结束并且不会产生错误消息,说明为什么没有创建窗口。

如果我从另一个C#程序中调用相同的C#库,则会按预期打印所有内容并创建窗口。

有人知道为什么Python for .NET在Forms构造器上无声地失败了吗?

2 个答案:

答案 0 :(得分:3)

在寻找另一个问题时偶然发现了这个问题。 我有点晚了,但我想我可以提供有关为什么会出现类似问题的人的情况。

当CPython解释器跟踪线程时,它会将它们放入 三类。

  • 正常
  • 守护程序
  • 外来

Normal用于通过线程模块启动的常规python线程。当任何这些或主线程正在运行时,解释器不会退出。

类似地,守护程序线程是通过线程模块启动的线程;但是,它们已被标记为守护进程。在他们的情况下,解释器不会在退出之前等待它们终止。

最后,外来线程是在与CPython相同的进程中启动的线程,但不是由任何python代码启动的。解释器知道这些,但不知道如何等待它们,所以像守护程序线程一样对待它们,并且不会在退出之前等待它们终止。

为了更好地处理Windows上的线程(加上没有GIL),请查看IronPython。它可能会更慢,但它只是处理这样的.NET交互,因为它作为本机.NET运行。

答案 1 :(得分:1)

当Python中的主线程终止时,它也会终止在.NET中运行的所有内容。

在上面给出的示例中,在将文本打印到终端之后,主Python线程终止之前,窗口还没有时间绘制。

在新的python线程内启动.NET调用会阻止此操作。