工作线程在到达 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() 必须在主线程上初始化,否则它不起作用。
这是演示 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() 必须在主线程上初始化,否则它不起作用。