工作线程到达使用Block C#Windows窗体应用程序时停止执行 [英] Worker Thread Stops execution when it reaches at Using Block C# Windows form application

查看:70
本文介绍了工作线程到达使用Block C#Windows窗体应用程序时停止执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是演示Windows窗体应用程序的外观:

This is how the demo windows form app looks like:

这是已实现的代码:

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;
    }
}

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

I asked this question because, I call C# function which use using(Py.GIL()) block and is executed with a new thread as shown on the above code. It works for the first round(sometimes it does not), and for the next round, it stops on the using block and the application stays the same with out showing any result or exception.

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

The application works if I removed the using(Py.GIL()) block, and do other stuff for the sake of testing. For example, Change the result label text to something else.

我在做什么错了?

已更新

问题不在LoadLibrary函数上.它在AnalyzeWord函数上.在LoadLibrary上,它可以成功执行它,但不能在AnalyzeWord函数上执行.

The problem is not on LoadLibrary function. It is on AnalyzeWord function. On LoadLibrary it successfully executes it but not on AnalyzeWord function.

推荐答案

我遵循@Damien的建议,提出了此解决方案,并成功了.

I followed the suggestion by @Damien and came up with this solution and it worked.

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()必须在主线程上初始化,否则它将不起作用.

PythonEngine.BeginAllowThreads() must be initialized on the Main thread or else it does not work.

初始化后,主线程将保留GIL,直到您通过从以下位置调用PythonEngine.BeginAllowThreads()显式释放它主线程(不是来自您的后台线程)

这篇关于工作线程到达使用Block C#Windows窗体应用程序时停止执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆