工作线程在到达 Using Block C# Windows 表单应用程序时停止执行

Worker Thread Stops execution when it reaches at Using Block C# Windows form application

这是演示 windows 表单应用的样子:

这是实现的代码:

public partial class HornMorphoWindow : Form
{
    private static dynamic _morpho;

    private static string _analyzeWord;

    private static Logger logger = LogManager.GetCurrentClassLogger();

    public delegate void StatusDelegate();

    public HornMorphoWindow()
    {
        InitializeComponent();
    }

    private void HornMorphoWindow_Load(object sender, EventArgs e)
    {
        var splashScreen = new Splash();  // This is Splash Form
        splashScreen.Show();

        Application.DoEvents(); // Force the splash screen to be shown

        Task.Factory.StartNew(LoadLibrary).Wait(); // Wait for the library to load

        splashScreen.Close();
    }

   // When a button clicked
   private void analyze_Click(object sender, EventArgs e)
   {
        if (string.IsNullOrEmpty(amharicInput.Text)) return;

        _analyzeWord = amharicInput.Text; // amharicInput is TextBox
        analyze.Enabled = false; // analyze is a button

        Task.Factory.StartNew(AnalyzeWord);
    }

    private static void LoadLibrary()
    {
        logger.Info("Loaidng Library.....");
        using (Py.GIL())
        {
            _morpho = Py.Import("l3");
            _morpho.load_lang("am");
        }
        logger.Info("Library Loaded Sucessfully!");
    }

    private void AnalyzeWord()
    {
        logger.Info("Word Analyzation Started. Word: " + _analyzeWord);

        using (Py.GIL())
        {
            _analyzeWord = _morpho.anal_word("am", _analyzeWord, Py.kw("nbest", 1));
        }

        logger.Info("Word Analyzation Ended. Result:\n " + _analyzeWord);

        try
        {
            this.Invoke(new StatusDelegate(UpdateStatus));
        }
        catch
        {
           // Some problem occurred
        }

     }

    private void copyButton_Click(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(result.Text)) return;

        Clipboard.SetText(result.Text, TextDataFormat.UnicodeText);
    }


    private void UpdateStatus()
    {
        result.Text = _analyzeWord; // result is a label

        copyButton.Visible = true; // copyButton shows up when result is successfull

        analyze.Enabled = true;
    }
}

我问这个问题是因为,我调用了使用 using(Py.GIL()) block 的 C# 函数,并使用新线程执行,如上面的代码所示。它在第一轮有效(有时无效),而在下一轮,它在 using block 停止并且应用程序保持不变,没有显示任何结果或异常。

如果我删除了 using(Py.GIL()) 块,应用程序会工作,并为了测试做其他事情。例如,将结果标签文本更改为其他内容。

我做错了什么?

已更新

问题不在 LoadLibrary 函数上。它在 AnalyzeWord 功能上。在 LoadLibrary 上成功执行,但在 AnalyzeWord 函数上没有。

我听从了@Damien 的建议并想出了这个解决方案并且它奏效了。

private void HornMorphoWindow_Load(object sender, EventArgs e)
{
    var splashScreen = new Splash();  // This is Splash Form
    splashScreen.Show();

    Application.DoEvents(); // Force the splash screen to be shown

    // The newly added line and the solution for the problem
    PythonEngine.Initialize();
    PythonEngine.BeginAllowThreads();
    //********************************

    Task.Factory.StartNew(LoadLibrary).Wait(); // Wait for the library to load

    splashScreen.Close();
}

PythonEngine.BeginAllowThreads() 必须在主线程上初始化,否则它不起作用。

The main thread will hold the GIL after initialization until you explicitly release it by calling PythonEngine.BeginAllowThreads() from the main thread (not from your background thread)