2011-08-14 3 views
0

winforms 앱이 있으며 Backgroundworker 스레드 내부에서 기본 폼의 Handle 속성에 액세스해야합니다.backgroundworker 스레드 내에서 Windows 양식에 올바르게 액세스하십시오.

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; 
    } 

나는 잘못하고 있습니까? 미리 감사드립니다.

나중에 편집 : 나는 처음부터 손잡이가 필요한 이유를 게시 할 것입니다. 아마도 다른 해결책/접근법이있을 것입니다. 내 Backgroundworker 스레드에서 루프에 여러 프로그램을 설치해야하며 각 설치 프로그램의 프로세스를 시작합니다. 그러나이 작업은 관리자뿐만 아니라 표준 사용자도 사용할 수 있도록 권한 상승을 요청해야합니다. 즉, 자습서를 따르려고합니다. here

답변

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(); 
    } 
} 
+0

방금 ​​시도했지만 IntPtr이 Control obj가 아님을 알았습니다. ect 따라서 InvokeRequired 또는 Invoke와 같은 속성이 없으므로이 정적 메서드를 스레드로부터 안전하게 호출 할 수 있습니다. –

+0

방금 ​​전에 생각한 것보다 코드가 더 깨졌습니다. 안전하지 않은 방식으로 'GetMainAppForm()'을 호출하여 스레드 세이프 방식으로 동일한 메소드를 호출해야하는지 여부를 판단합니다. 그건 말이 안돼. 어쨌든, 나는 나의 대답을 업데이트했고 더 많은 코드를 포함시켰다. – Codo

+0

의견을 보내 주셔서 감사합니다. 즉, GetMainAppForm(), InvokeRequired 또는 updaterObj = GetMainAppForm()에서 코드에 의미가없는 부분을 의미합니다. Updater (Invoke)를 호출합니까? –

관련 문제