c# – 将工作人员与UI线程同步
在现有的项目中,我必须使用WinForms(一段时间没有使用它),并且与UI线程同步有一个问题.
我必须与以下工作集成的设计:BackgroundWorker获取一个Action作为参数,并以异步方式执行.我正在开展的行动有两部分:一个核心类(包含业务逻辑)和一个GUI部分,通过事件通知核心,如果它必须请求用户交互. 我已经将句柄创建添加到窗体的构造函数 if (!IsHandleCreated) { //be sure to create the handle in the constructor //to allow synchronization with th GUI thread //when using Show() or ShowDialog() CreateHandle(); } 这样,以下代码工作: private DialogResult ShowDialog(Form form) { DialogResult dialogResult = DialogResult.None; Action action = delegate { dialogResult = form.ShowDialog(); }; form.Invoke(action); return dialogResult; } 对于此示例,启动位置已设置为Windows默认值. 如果我把它改成: Action action = delegate { dialogResult = form.ShowDialog(ParentWindow); }; 其中ParentWindow是IWin32Window的实例,并且WindowStartupLocation设置为CenterParent.调用form.Invoke(action)时,我得到一个跨线程异常.
问题: >为什么只有在将启动位置设置为CenterParent时,才会出现跨线程异常?我该如何避免呢? 两者都可能相关! [编辑] private static void OnActivationConfirmationRequired(DmsPackageConfiguratorCore sender,ConfigurationActivationConfirmationEventArgs args) { args.DoAbort = (ShowDialog(new ActivationConfirmationForm(args.Data)) == DialogResult.No); } 我处理的一切都在GUI界面 /// <summary> /// Interface defining methods and properties used to show dialogs while performing package specific operations /// </summary> public interface IPackageConfiguratorGui { /// <summary> /// Gets or sets the package configurator core. /// </summary> /// <value>The package configurator core.</value> IPackageConfiguratorCore PackageConfiguratorCore { get; set; } /// <summary> /// Gets or sets the parent window. /// </summary> /// <value>The parent window.</value> IWin32Window ParentWindow { get; set; } /// <summary> /// Gets the package identifier. /// </summary> /// <value>The package identifier.</value> PackageIdentifier PackageIdentifier { get; } } 解决方法
看到form.InvokeRequired在false是你的问题的核心.你知道它必须是真实的.简单的解释是传递给您的ShowDialog()方法的表单对象是错误的对象.经典的错误是使用new来创建实例,而不是使用窗体对象的现有实例,即用户正在查看并在主线程上创建的实例.确保线程代码具有对该表单对象的引用,以便它可以传递正确的引用.只有使用Application.OpenForms [0],如果你不能正确的话.
一般来说,将线程代码与用户界面分离.工作线程没有显示对话的业务.你可以使它工作,但它在实践中不能很好地工作.弹出对话框,无需用户期待.发生事故可能,用户可能会在弹出对话框之前点击或按下键几分之一秒.关闭对话框,甚至不看它. CreateHandle()hack同样不应该在您的代码中.只需在用户界面准备好之前不要启动线程.由表单的Load事件发出信号. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 关联、组合、聚合、依赖关系比较
- flex中,如何使用SharedObject的一个小例子
- swift-playground – 元素序列,但“join is unavailable:调
- 谁阻止跨域AJAX请求浏览器或网络服务器或两者?
- ruby – bundle.setup和bundle.require有什么区别?
- (PLSQL + Oracle 11g 64bit + 32位oci.dll文件) 访问Oracle
- c – 使用调试版覆盖新版,而不会损坏新版本
- 21.Oracle杂记——Oracle报告类脚本
- 单元测试 – Jest – 模拟在React组件内部调用的函数
- 从两个可能的数字(4或7)中获取一个数字并返回第二个数字的函