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コード

Pythonfor.NETとPython2.7for 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」も出力されず、実際にウィンドウは作成されません。Pythonプログラムは終了し、ウィンドウが作成されなかった理由を示すエラーメッセージは生成されません。

別のC#プログラムから同じC#ライブラリを呼び出すと、すべてが期待どおりに印刷され、ウィンドウが作成されます。

Python for .NETがFormsコンストラクターでサイレントに失敗する理由を誰かが知っていますか?

4

2 に答える 2

3

別の質問を探しているときに、この質問に出くわしました。少し遅れましたが、同様の問題を抱えている人になぜこれが起こるのかについての洞察を提供できると思います.

CPython インタプリタがスレッドを追跡するとき、それらを 3 つのカテゴリに分類します。

  • 普通
  • デーモン
  • エイリアン

Normal は、threading モジュールを通じて開始された通常の Python スレッド用です。これらのいずれかまたはメインスレッドが実行されている間、インタープリターは終了しません。

同様に、デーモン スレッドは、threading モジュールを通じて開始されるスレッドです。ただし、それらはデーモンとしてマークされています。その場合、インタープリターは終了する前に終了するのを待ちません。

最後に、エイリアン スレッドは、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 に答える