1

与えられた

Action closeLoadingAction = new Action(() =>
{
  loadingForm.Close();
  #region - may need to put into second Action
  panelOnMainForm.Controls.AddRange(physdocControls.ToList<Control>().ToArray());
  if (Handle != IntPtr.Zero)
    User32DLL.SetForegroundWindow(this.Handle);//Handle is a property of the mainForm.
  #endregion
});

必要な呼び出しをチェックしても、ハンドルが作成されていない例外が発生することがあります。

if(loadingForm.InvokeRequired)
   loadingForm.Invoke(closeLoadingAction);
else
   closeLoadingAction();

ロードフォームは、メインフォームと同じスレッドで実行されます。上記のコードは別のスレッドで実行されます。メインフォームに対して呼び出すための別のチェックが必要だと思います。2回目のチェックが必要ですか、それともすでに安全ですか?

4

3 に答える 3

2

上記のコードは別のスレッドで実行されます

コードが別のスレッドで実行されることがわかっている場合に、このようにInvokeRequiredを使用することは、悪いアンチパターンです。あなたはそれを使ってはるかに便利なことをすることができます。好き:

if (!loadingForm.InvokeRequired) {
    throw new InvalidOperationException("Threading race detected");
}
loadingForm.Invoke(closeLoadingAction);

または、読み込みフォームのLoadイベントが発生する前に読み込みスレッドを開始する場合は、より実用的な方法です。

while (!loadingForm.InvokeRequired) Thread.Sleep(50);
loadingForm.Invoke(closeLoadingAction);

または、正しい方法で実行し、フォームのLoadイベントでスレッドを開始します。

于 2012-11-06T05:02:09.417 に答える
1

Invokeデリゲートを試みる前にフォームが表示されていないか閉じられている場合にのみ、これらの「ハンドルが作成されていません」という例外が発生するはずです。ただし、それが当てはまるかどうかを判断するのに十分なコードがないため、私があなたの立場にあるClosed場合は、メソッドが実際に呼び出される前に、読み込みフォームの(呼び出し側であるため)イベントが呼び出されているかどうかを判断しようとします。

InvokeRequired両方のフォームが同じスレッド上にあるため、読み込み中のフォームのプロパティを確認するだけで安全です。一般的に、メインフォームを操作する場合は、そのフォームのInvokeRequiredプロパティを確認する必要があります。同様に、(Close上記の呼び出しのように)読み込みフォームを操作する場合は、読み込みフォームのInvokeRequiredプロパティを確認する必要があります。上であなたが変わっpanelOnMainFormているので、私はそれが完全に安全であることを確認しますが、それが必要であるとは思いません。

于 2012-11-06T02:18:31.913 に答える
1

loadingForm作成中のハンドルとへの呼び出しの間の競合のように聞こえloadingForm.Close()ます。

これを回避する1つの方法は、イベントが発生したときに.Invoke/.Closeコードを持つスレッドを開始することです。loadingForm.HandleCreated

private void loadingForm_HandleCreated(object sender, EventArgs e)
{
    var t = new Thread(DoLoadingStuff);
    t.Start();
}

private void DoLoadingStuff()
{
    // ...

    if(loadingForm.InvokeRequired)
       loadingForm.Invoke(closeLoadingAction);
    else
       closeLoadingAction();
}
于 2012-11-06T05:05:08.223 に答える