Worker Thread Stops execution when it reaches at U

2019-06-14 10:24发布

This is how the demo windows form app looks like:

enter image description here

And this is the implemented code:

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

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.

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.

What am I doing wrong?

UPDATED

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

1条回答
Summer. ? 凉城
2楼-- · 2019-06-14 11:11

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() must be initialized on the Main thread or else it does not work.

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)

查看更多
登录 后发表回答