c# – 将工作人员与UI线程同步

c# – 将工作人员与UI线程同步,第1张

概述在现有的项目中,我必须使用WinForms(一段时间没有使用它),并且与UI线程同步有一个问题. 我必须与以下工作集成的设计:BackgroundWorker获取一个Action作为参数,并以异步方式执行.我正在开展的行动有两部分:一个核心类(包含业务逻辑)和一个GUI部分,通过事件通知核心,如果它必须请求用户交互. 我已经将句柄创建添加到窗体的构造函数 if (!IsHandleCreated) 在现有的项目中,我必须使用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)时,我得到一个跨线程异常.

Cross-thread operation not valID: Control ‘ActivationConfirmationForm’ accessed from a thread other than the thread it was created on.

问题:

>为什么只有在将启动位置设置为CenterParent时,才会出现跨线程异常?我该如何避免呢?
>为什么form.Invokerequired总是假的?

两者都可能相关!

[编辑]
@Reniuz:
你没有在这里丢失任何东西;)
该呼叫正在由核心通知的听众进行

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],如果你不能正确的话.

一般来说,将线程代码与用户界面分离.工作线程没有显示对话的业务.你可以使它工作,但它在实践中不能很好地工作.d出对话框,无需用户期待.发生事故可能,用户可能会在d出对话框之前点击或按下键几分之一秒.关闭对话框,甚至不看它. CreateHandle()Hack同样不应该在您的代码中.只需在用户界面准备好之前不要启动线程.由表单的Load事件发出信号.

总结

以上是内存溢出为你收集整理的c# – 将工作人员与UI线程同步全部内容,希望文章能够帮你解决c# – 将工作人员与UI线程同步所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1261089.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存