当调用后台工作程序将文本附加到闪烁控件时,后台工作程序会暂停,这是部分代码。添加try-catch逻辑后,我仍然没有得到任何异常!
private delegate void DWrite(string text);
private void Write(string text)
{
try
{
scintilla1.AppendText(text);
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
string x;
while (true)
{
x = tcw.Read();
// MessageBox.Show(x);
Thread.Sleep(100);
try
{
scintilla1.Invoke(new DWrite(Write), x);
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
// scintilla1.Update();
}
我添加了这个逻辑:
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
MessageBox.Show("MyHandler caught : " + e.Message);
}
public void doworkstuff()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
try
{
for (int i = 0; i < 5; i++)
scintilla1.Invoke(new DWrite(Write), tcw.Read());
}
catch (Exception ex)
{ MessageBox.Show(ex.ToString()); }
}
问题似乎出在控件本身,不允许外部线程访问以避免死锁。有没有一种方法可以让我在不使用BGWorker的情况下获得相同的功能?tcw.read()是一个telnet客户端,它将输入流式传输到控件,我希望流式传输(即tcw.read())继续进行,直到用户在表单上按下stop!
您在ScintillaNET中发现了一个错误。
为了处理托管Scintilla包装器和本机Scintilla控件之间的互操作,ScintillaNET重写WndProc方法。在这样做的过程中,似乎破坏了将调用封送回UI线程的Windows窗体机制。
在此期间,您可以使用BackgroundWorker。ProgressChanged事件,用于精确执行您正在尝试的定期UI更新类型。
在确保设置了BackgroundWorker之后。WorkerReportsProgress属性设置为true
,修改代码以便使用BackgroundWorker。ReportProgress方法代替Invoke方法并处理ProgressChanged事件。
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
string x;
while (true)
{
x = "Your telnet data";
Thread.Sleep(100);
worker.ReportProgress(-1, x);
}
}
private void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string text = e.UserState as string;
scintilla1.AppendText(text);
}
(完整披露:我是ScintillaNET的开发人员)
您应该设置一些中断条件,while循环是一个无限循环!如果使用BeginInvoke而不是Invoke,则后台工作程序不会停止!
scintilla1.BeginInvoke(new DWrite(Write), x);