правильный доступ к форме окна внутри потока backgroundworker - PullRequest
0 голосов
/ 14 августа 2011

У меня есть приложение 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 Ответ

1 голос
/ 14 августа 2011

Вы не получаете ручку потокобезопасным способом. Вместо этого вы получаете экземпляр 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();
    }
}
...