这是演示窗口窗体应用程序的样子:
这是实现的代码:
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 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() 必须在主线程上初始化,否则它不起作用。
主线程将在初始化后保留 GIL,直到您通过从主线程(而不是从您的后台线程)调用 PythonEngine.BeginAllowThreads() 显式释放它
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句