我有一个winforms应用程序,我需要访问Backgroundworker线程内主窗体的Handle属性。在backgroundworker线程内正确访问一个windows窗体
我做了一个调用带InvokeRequired的主窗体的线程安全方法。我的问题是 - 为什么我仍然得到“InvalidOperationException异常跨线程操作无效”的错误,调用此线程,即使安全的方法是这样的:
ProcessStartInfo psi = new ProcessStartInfo(file);
psi.ErrorDialogParentHandle = Utils.GetMainAppFormThreadSafe().Handle;
而下方则是线程安全的方法的代码(我的主应用程序的形式称为更新):
/// <summary>
/// delegate used to retrieve the main app form
/// </summary>
/// <returns></returns>
private delegate Updater delegateGetMainForm();
/// <summary>
/// gets the mainform thread safe, to avoid cross-thread exception
/// </summary>
/// <returns></returns>
public static Updater GetMainAppFormThreadSafe()
{
Updater updaterObj = null;
if (GetMainAppForm().InvokeRequired)
{
delegateGetMainForm deleg = new delegateGetMainForm(GetMainAppForm);
updaterObj = GetMainAppForm().Invoke(deleg) as Updater;
}
else
{
updaterObj = GetMainAppForm();
}
return updaterObj;
}
/// <summary>
/// retrieves the main form of the application
/// </summary>
/// <returns></returns>
public static Updater GetMainAppForm()
{
Updater mainForm = System.Windows.Forms.Application.OpenForms[Utils.AppName] as Updater;
return mainForm;
}
我做错了吗? 预先感谢您。
后期编辑:我会发布为什么我需要首先处理的原因,也许有另一种解决方案/方法。在我的Backgroundworker线程中,我需要在循环中安装多个程序,并为每个安装程序启动一个进程。不过,我需要提升高度,以便此操作可以为标准用户工作,而不仅仅是管理员。总之,我试图按照教程here
我刚试过这个,但意识到IntPtr不是控制对象因此没有像InvokeRequired或Invoke这样的属性,因此我可以以线程安全的方式调用此静态方法。 –
我刚刚意识到你的代码比我第一次想到的更糟糕:你以不安全的方式调用'GetMainAppForm()'来确定是否需要以一种线程安全的方式调用相同的方法。这是没有意义的。无论如何,我已经更新了我的答案并包含更多代码。 – Codo
感谢您的评论 - 你的意思是没有任何意义的部分在我的代码中:GetMainAppForm()。InvokeRequired或updaterObj = GetMainAppForm()。调用(委托)作为更新? –