Правильный доступ к форме окна внутри потока backgroundworker
У меня есть приложение winforms, и мне нужно получить доступ к свойству Handle основной формы внутри потока Backgroundworker.
Я сделал потокобезопасный метод, который вызывает основную форму с 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 мне нужно установить несколько программ в цикле, и я запускаю процесс для каждого установщика. Однако мне нужно запросить повышение прав, чтобы эта операция могла работать и для обычных пользователей, а не только для администраторов. Короче, я пытаюсь следовать учебнику здесь
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();
}
}