gpt4 book ai didi

c# - Form.Show()导致Visual Studio 2010中的InvalidOperationException,该异常在2008年不存在

转载 作者:行者123 更新时间:2023-12-03 13:21:54 25 4
gpt4 key购买 nike

我有一些采用表单​​对象(winforms)并在专用线程上调用form.Show()的代码(它旋转一个新线程)。
在Visual Studio 2008(框架3.5)中,此功能运行良好。我现在迁移到2010,但失败了
“InvalodOperationException:“跨线程操作无效:控件”是从创建该线程的线程之外的其他线程访问的。”

(当然,我们的一半文件已 checkout 进行迁移,整个团队正在等待...)

这是一些代码(这是正在运行的代码,因此让我迷失了一些冗余的详细信息):

    private void ShowForm(object container)
{
FormContainer formContainer = (FormContainer)container;
Process sboProcess = GetSboProcess();
if (sboProcess != null)
{
WindowWrapper MyWindow = new WindowWrapper(sboProcess.MainWindowHandle);
if (formContainer.ShowDialog)
{
formContainer.Form.ShowDialog(MyWindow);
}
else
{
//formContainer.Form.Invoke((MethodInvoker)delegate() { formContainer.Form.Show(MyWindow); });
formContainer.Form.Show(MyWindow);
//Run thread while form is opened:
System.Windows.Forms.Application.Run(formContainer.Form);
}
}
}



public class FormContainer
{
private readonly Form form;
private readonly bool showDialog;

public FormContainer(Form form, bool showDialog)
{
this.form = form;
this.showDialog = showDialog;
}

public bool ShowDialog
{
get { return showDialog; }
}

public Form Form
{
get { return form; }
}

}

public class WindowWrapper : IWin32Window
{
private readonly IntPtr handle;

public WindowWrapper(IntPtr handle)
{
this.handle = handle;
}

#region Implementation of IWin32Window

/// <summary>
/// Gets the handle to the window represented by the implementer.
/// </summary>
/// <returns>
/// A handle to the window represented by the implementer.
/// </returns>
/// <filterpriority>1</filterpriority>
public IntPtr Handle
{
get { return handle; }
}

#endregion
}

有人有主意吗?

谢谢,

阿舍尔

最佳答案

用一句话专用线程必须回调拥有该表单的UI线程。跨线程UI操作是非法的,因为某些操作可能导致所涉及的UI控件与Windows消息泵分离。这是一件坏事,因为Windows无法告诉窗口执行任何操作,包括绘制自身,移动甚至关闭。窗口变为“流氓”,并且所有Windows可以做的就是终止产生该窗口的整个过程。

form方法的调用可以是同步操作,也可以是异步操作,但是无论哪种方式,都必须排队等待它才能由UI线程运行。

这是一种从后台线程SEEM进行调用的方法,就像它们由后台线程执行一样,而不会违反跨线程规则:

//in your form class
public new void Show()
{
if(!InvokeRequired)
base.Show();
else
this.Invoke((MethodInvoker)(()=>base.Show()));
}

了解您不能将表单作为其基类System.Windows.Form来处理;它必须是您创建的具体表单类。否则,将忽略方法隐藏,并且默认情况下使用基本实现。

通过这种方式进行设置,每当某个操作可能要从后台线程运行时,就可以避免跨线程操作。如果需要,可以通过在控件上调用BeginInvoke()而不是Invoke()来将此方法更改为异步运行,但是由于对Show()的调用通常会同步运行,因此我会坚持使用Invoke。

关于c# - Form.Show()导致Visual Studio 2010中的InvalidOperationException,该异常在2008年不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6257434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com