我有一个winforms应用程序,我需要在Backgroundworker线程中访问主窗体的Handle属性。
我已经创建了一个使用InvokeRequired调用主窗体的线程安全方法。我的问题是 - 为什么我仍然得到“InvalidOperationException跨线程操作无效”错误,即使调用这样的线程安全方法:
ProcessStartInfo psi = new ProcessStartInfo(file);
psi.ErrorDialogParentHandle = Utils.GetMainAppFormThreadSafe().Handle;
以下是线程安全方法的代码(我的主应用程序表单称为Updater):
/// <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;
}
我做错了吗? 提前谢谢。
稍后编辑:我将首先发布我需要手柄的原因,也许还有另一种解决方案/方法。在My Backgroundworker线程中,我需要在循环中安装多个程序,并为每个安装程序启动一个进程。但是我需要提升,以便此操作也适用于标准用户,而不仅仅是管理员。简而言之,我正在尝试按照教程here
答案 0 :(得分:1)
您没有以线程安全的方式获取句柄。相反,您以线程安全的方式获取Form
实例,然后以不安全的方式访问Handle
属性。
您应该添加一个方法GetMainAppFormHandle()
,它直接返回句柄并以线程安全的方式调用该句柄:
public static IntPtr GetMainAppFormHandle()
{
return System.Windows.Forms.Application.OpenForms[Utils.AppName].Handle;
}
<强>更新强>
此外,您需要GetMainAppFormHandleThreadSafe()
而不是GetMainAppFormThreadSafe()
:
public static IntPtr GetMainAppFormHandleThreadSafe()
{
Form form = GetMainAppForm();
if (form.InvokeRequired)
{
return (IntPtr)form.Invoke(new Func<IntPtr>(GetMainAppFormHandle));
}
else
{
return GetMainAppFormHandle();
}
}