2

単一のメソッドでインターフェースを定義する外部フレームワークを使用しています。

bool Authenticate();

つまり、ユーザーインタラクション(WinForms)を含む、認証のプロセス全体が含まれます。私がやりたいことは次のようなものです:

bool Authenticate()
{
  bool succeeded = false;
  bool userCancelled = false;
  while(!succeeded && !userCancelled)
  {
     var credentials = AskTheUserForCredentials(); // this needs to wait for user input before returning!
     if (credentials == null) 
       userCancelled = true;
     else
       succeeded = AuthenticateWithAnExternalServer(credentials);

     if (!succeeded)
       ShowErrorMessage();
  }
  return succeeded;
}

これで、実装が簡単になり、AskTheUserForCredentials()内部でShowErrorMessage()使用することができます。Form.ShowDialog()これは、実際の認証プロセスのダイアログが消え、新しい、クリックして閉じる必要のあるダイアログにエラーメッセージが表示されるため、ユーザーエクスペリエンスが非常に悪くなります。

むしろ、すべてを1つの形式で表示したいのですが、それは表示されたままで、テキストボックス/ボタンを適切に無効にし、エラーメッセージを単独で表示します。

この単一のブロッキングメソッド呼び出しでどのように実行しますか?

アップデート

これまでの最善の解決策は、内部にメッセージポンプを実装することですAskTheUserForCredentials()

Credentials AskTheUserForCredentials()
{
   while(NeitherOkNorCancelPressed())
   {
      Application.DoEvents();
      Thread.Sleep(10); // Standard Sleep(0) results in 100% procesor core usage.
   }
   return CreateCredentialsFromTextboxesEtc();
}

今、私たちは皆、メッセージポンプがきれいにはほど遠いことを知っています。

このソリューションは正確にどれほど悪いですか?

何か良いですか?

更新2

メッセージポンプにはいくつかの落とし穴がありました。

  • 醜く、CPU効果が十分ではない

  • ホワイトUIAutomationでの動作が非常に遅い

最終的に、プロセス全体をChrisBDとしてダイアログに委任しました(ダイアログは、最終的に成功または失敗した後にのみ閉じます)。これは、IoCを使用してGUIから認証を抽象化するのに時間がかかりましたが、最終的にはクリーンで意図したとおりに機能します。

4

1 に答える 1

1

私はあなたがほとんどそこにいると思います。

ユーザー入力コントロールを持つモーダル ダイアログを表示し、必要に応じてそのダイアログで Authenticate メソッドを呼び出すようにします。

次に、ダイアログを閉じるタイミングと、実際にエラー メッセージが表示される場所を選択できます。

モーダル ダイアログ クラスのプロパティに、認証が成功したかどうかを示すようにします。ダイアログ クラス (モーダルで開く前にメイン アプリケーションによってインスタンス化されたもの) を閉じると、メイン アプリケーションは引き続き実行されます。その後、適切なダイアログ クラス プロパティをチェックすることで、認証が成功したかどうかを確認できます。

*ここで編集*

Authenticate メソッドを自分で実装している場合、(前述のように) メイン アプリケーションではなく、モーダル ダイアログを呼び出すのはこの関数です。カスタム フォーム クラスは、すべての認証ロジックを実行し、エラー メッセージと共にユーザー操作コントロールを表示できます。最小化ボタンと閉じるボタンを削除し、認証プロセスの成功または失敗を示すクラス プロパティを設定することを忘れないでください。

呼び出し元のフレームワークは、認証メソッドの戻り値を待ちます。

于 2012-01-04T10:51:42.433 に答える