Python for .NET 中的一些线程问题

77 阅读1分钟

在使用 Python for .NET 框架时,调用 System.Windows.Forms.Form 构造函数时,程序可能会静默失败。例如,以下 C# 代码将创建一个窗口并在控制台输出一些信息:

image.png

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);
            http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
            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 for .NET 框架调用这个C#库中的CreateWindow()方法时,Python程序会静默失败,不会输出任何错误信息。

2.解决方案 有两种方法可以解决这个问题:

  • 在新的Python线程中调用.NET方法。这将确保当Python主线程终止时,.NET线程不会被终止。可以使用以下代码在Python中创建一个新的线程:
import clr
clr.AddReference("MinimalFormsApp")

from WindowsFormsTest import CreateACoolWindow
CreateACoolWindow.CreateWindow()

# Start a new Python thread to call the .NET code
import threading
def run_in_new_thread():
    CreateACoolWindow.CreateWindow()
threading.Thread(target=run_in_new_thread).start()

#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."
  • 使用IronPython。IronPython是一个Python实现,可以与.NET框架无缝集成。使用IronPython,可以像使用C#一样调用.NET方法,而不会遇到上述问题。

另外,也需要注意,当Python主线程终止时,它也会终止所有的.NET线程。因此,在Python程序中调用.NET方法时,需要确保Python主线程不会在.NET线程完成工作之前终止。