来自后台辅助角色的文件对话框
本文关键字:文件 对话框 角色 后台 | 更新日期: 2023-09-27 18:34:18
在维护一些代码时,我发现我们在后台工作线程中有一个无限的挂断。工作人员需要访问脚本文件。编写原始代码是为了在未定义脚本文件时弹出文件对话框,以允许用户选择一个。它看起来像这样:
private void bgworker_DoWork(object sender, DoWorkEventArgs e)
{
... snip ...
if (String.IsNullOrWhitespace(scriptFile))
{
scriptFile = PromptForScript();
}
... snip ...
}
private string PrompForScript()
{
string script = "";
OpenFileDialog openDialog = new OpenFileDialog();
if (openDialog.ShowDialog() == DialogResult.OK)
{
script = openDialog.FileName;
}
return script;
}
我已经阅读了一些关于MethodInvoker
的信息,但几乎所有的调用方法都要求您从控件调用它们。有问题的后台工作线程正在从单独的类运行,该类不会扩展Control
。我是否为此使用调用 bgworker 的类的形式?还是有另一种中断线程以供用户输入的方法?
不建议从后台辅助角色 DoWork 事件处理程序调用 UI。 BackgroundWorker
旨在对非 UI 线程执行工作以保持 UI 响应。 在以 RunWorkerAsync
开头BackgroundWorker
对象之前,应询问任何文件信息。
您要做的是捕获 UI 线程上的同步上下文并将其传递给后台工作线程。 BackgroundWorker 可以在上下文中调用Send()
(同步,如Invoke
)和Post()
(异步,如BeginInvoke
)以调用回正确的 UI 线程。 也就是说,在这种情况下可能不需要 BackgroundWorker - 常规线程池线程就可以了。
这个(略有修改的)http://msmvps.com/blogs/manoj/archive/2005/11/03/74120.aspx 代码块应该给你一个大致的想法:
private void button1_Click(object sender, EventArgs e)
{
// Here we are on the UI thread, so SynchronizationContext.Current
// is going to be a WindowsFormsSynchronizationContext that Invokes properly
ctx = SynchronizationContext.Current;
ThreadPool.QueueUserWorkItem(
// This delegate is going to be invoked on a background thread
s => {
// This uses the context captured above to invoke
// back to the UI without the "messy" referencing
// of a particular form
ctx.Send(s2 =>
{
// Interact with your UI here- you are on the UI thread
},null);
}
);
}
如果某个窗体在使用 BGworker 的另一个类中启动了一个长时间运行的进程,为什么窗体(或表示器,取决于 UI 体系结构)不处理错误状态的处理?
也许,只是传回一些状态结果(或抛出一个非常有针对性的特定异常,你可以在 UI 中处理)?
让后台工作线程确定是否存在错误,但将错误(尤其是显示消息框的 UI 部分)留给上层。
抱歉,这没有更具体的代码,但它可能会有很多不同的方式,具体取决于您的系统架构方式。
嗯,Form
类有一个Invoke
方法,因此将表单实例传递给后台工作类应该可以工作。