I'm using an external framework that defines an interface with a single method:
bool Authenticate();
that is to contain the whole process of authentication, including user interaction (WinForms). What I would like to do is something like:
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;
}
Now the easy way to implement AskTheUserForCredentials()
and ShowErrorMessage()
is to use Form.ShowDialog()
inside. This is really bad user experience, as the dialog disappears for the actual authentication process and error message appears in a new, have-to-click-to-close dialog.
I'd rather have it all in a single form, that stays visible, disables textboxes/buttons appropriately and displays the error message by itself.
How would you do it in this single, blocking method call?
UPDATE
Best solution so far is to implement a message pump inside AskTheUserForCredentials()
:
Credentials AskTheUserForCredentials()
{
while(NeitherOkNorCancelPressed())
{
Application.DoEvents();
Thread.Sleep(10); // Standard Sleep(0) results in 100% procesor core usage.
}
return CreateCredentialsFromTextboxesEtc();
}
Now we all know message pumps are far from clean.
Exactly how bad is this solution?
Anything better?
UPDATE 2
The message pump had some pitfalls:
being ugly and not fully cpu-effective
working terribly slow with White UIAutomation
I ended up delegating the whole process to a dialog as ChrisBD (the dialog only closes after ultimate success or failure). This took more time to abstract the authentication away from the GUI with IoC, but eventually is clean and works as intended.