我有一個winforms應用程序,我需要訪問Backgroundworker線程內主窗體的Handle屬性。在backgroundworker線程內正確訪問一個windows窗體
我做了一個調用帶InvokeRequired的主窗體的線程安全方法。我的問題是 - 爲什麼我仍然得到「InvalidOperationException異常跨線程操作無效」的錯誤,調用此線程,即使安全的方法是這樣的:
ProcessStartInfo psi = new ProcessStartInfo(file);
psi.ErrorDialogParentHandle = Utils.GetMainAppFormThreadSafe().Handle;
而下方則是線程安全的方法的代碼(我的主應用程序的形式稱爲更新):
/// <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
我剛試過這個,但意識到IntPtr不是控制對象因此沒有像InvokeRequired或Invoke這樣的屬性,因此我可以以線程安全的方式調用此靜態方法。 –
我剛剛意識到你的代碼比我第一次想到的更糟糕:你以不安全的方式調用'GetMainAppForm()'來確定是否需要以一種線程安全的方式調用相同的方法。這是沒有意義的。無論如何,我已經更新了我的答案幷包含更多代碼。 – Codo
感謝您的評論 - 你的意思是沒有任何意義的部分在我的代碼中:GetMainAppForm()。InvokeRequired或updaterObj = GetMainAppForm()。調用(委託)作爲更新? –