私は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がControl objではないことに気づきました私はこの静的メソッドをスレッドセーフな方法で呼び出すことができるように、InvokeRequiredやInvokeのようなプロパティはありません。 –
私はあなたのコードが最初に思ったよりも壊れていることに気づきました。つまり、同じメソッドをスレッドセーフな方法で呼び出す必要があるかどうかを判断するために、安全でない方法で 'GetMainAppForm()'を呼び出します。それは意味をなさない。とにかく、私は私の答えを更新し、より多くのコードを含んでいます。 – Codo
コメントをいただきありがとうございます - 私のコードには意味をなさない部分があります:GetMainAppForm()。InvokeRequired、またはupdaterObj = GetMainAppForm()。Updater(Invoke)を呼び出しますか? –