问题
This is how the demo windows form app looks like:
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:
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)
来源:https://stackoverflow.com/questions/42759968/worker-thread-stops-execution-when-it-reaches-at-using-block-c-sharp-windows-for