Правильный доступ к форме окна внутри потока 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();
    }
}
Другие вопросы по тегам