3

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 在控制台上打印的内容

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

它的羊毛像雪一样白;
玛丽所到之处,她的小羊一定会去。
FormSubClass 构造函数调用

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

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

有谁知道为什么 Python for .NET 在 Forms 构造函数上静默失败?

4

2 回答 2

3

在寻找另一个问题时偶然发现了这个问题。我有点晚了,但我想我可以深入了解为什么会有类似问题的人发生这种情况。

当 CPython 解释器跟踪线程时,它将它们分为三类。

  • 普通的
  • 守护进程
  • 外星人

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

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

最后,外来线程是在与 CPython 相同的进程中启动但不是由任何 python 代码启动的线程。解释器知道这些但不知道如何等待它们,因此将它们视为守护线程,并且在退出之前不等待它们终止。

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

于 2013-07-24T17:11:14.740 回答
1

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

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

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

于 2013-03-26T06:01:06.250 回答