I am developing and application that loads a large amount of front end data when the program is opened. To let the user know the program has started I want to show a splash screen while it checks for the user login as well as load additional information. The issue I am having is I can't get the splash screen to stay visible with out dead locking the application.
public ProgramMain()
{
InitializeComponent();
LoadDataAsync().Wait();
_viewPageManager = new ViewPageManager(MainTabControl);
}
protected async Task LoadDataAsync()
{
StartUp.StartUpForm progressForm = new StartUp.StartUpForm();
progressForm.Show();
// 'await' long-running method by wrapping inside Task.Run
await Task.Run(() =>
{
AppSetting setting = new AppSetting();
SqlHelper helper = new SqlHelper(setting.GetConnectionString("cn"));
if(!helper.HandShake())
{
UserLogin userLogin = new UserLogin();
if(userLogin.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("Logged In");
return Task.FromResult(true);
}
else
{
return Task.FromResult(false);
}
}
else
{
return Task.FromResult(true);
}
}
).ContinueWith(new Action<Task>(task =>
{
//if (this.IsHandleCreated)
// Close modal dialog
// No need to use BeginInvoke here
// because ContinueWith was called with TaskScheduler.FromCurrentSynchronizationContext()
progressForm.Close();
}), TaskScheduler.FromCurrentSynchronizationContext());
}
public class ProgramStartUp : WindowsFormsApplicationBase
{
protected override void OnCreateSplashScreen()
{
SplashScreen = new StartUp.StartUpForm();
}
protected override void OnCreateMainForm()
{
var task = Task.Run(() => LoadDataAsync());
task.Wait();
MainForm = new ProgramMain();
}
protected async Task LoadDataAsync()
{
// 'await' long-running method by wrapping inside Task.Run
bool handshakeSuccessful = await Task.Run(() =>
{
AppSetting setting = new AppSetting();
SqlHelper helper = new SqlHelper(setting.GetConnectionString("cn"));
if (!helper.HandShake())
{
UserLogin userLogin = new UserLogin();
if (userLogin.ShowDialog() == DialogResult.OK)
{
return true;
}
}
return false;
});
}
}
I am new to using threads so let me know if this is correct.
protected override void OnCreateMainForm()
{
SystemUsers users = new SystemUsers();
var progress = new Progress<LoginStatus>();
LoginStatus status = new LoginStatus();
while (status != LoginStatus.Success || status == LoginStatus.Disconnected)
{
if (status != LoginStatus.Failure) { status = Task.Run(async () => await users.Login(progress)).GetAwaiter().GetResult(); }
string userName = "";
string password = "";
if (status == LoginStatus.Failure)
{
UserLogin userLogin = new UserLogin(users);
if (userLogin.ShowDialog() == DialogResult.Continue)
{
userName = userLogin.UserName;
password = userLogin.Password;
}
else
{
status = LoginStatus.Disconnected;
}
status = Task.Run(async () => await users.Login(progress, userName, password)).GetAwaiter().GetResult();
if (status == LoginStatus.Failure)
{
MessageBox.Show("Error Incorrect Username or Password Entered", "Invlaid User Information", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
MainForm = new StruHubMain(users);
}
public async Task<LoginStatus> Login(IProgress<LoginStatus> progress)
{
LoginStatus loginStatus = new LoginStatus();
loginStatus = LoginStatus.Attempt;
if (progress != null) { progress.Report(loginStatus); }
await Task.Run(() =>
{
AppSetting setting = new AppSetting();
SqlHelper helper = new SqlHelper(setting.GetConnectionString("cn"));
if (helper.HandShake())
{
setting.SaveConnectionString("conn", setting.GetConnectionString("conn"));
_currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
if (_users == null && fillUsers)
{
FillUsers();
}
loginStatus = LoginStatus.Success;
}
else
{
loginStatus = LoginStatus.Failure;
}
});
progress.Report(loginStatus);
return loginStatus;
}
public async Task<LoginStatus> Login(IProgress<LoginStatus> progress,string userName, string password)
{
LoginStatus loginStatus = new LoginStatus();
loginStatus = LoginStatus.Attempt;
if (progress != null) { progress.Report(loginStatus); }
await Task.Run(() =>
{
AppSetting setting = new AppSetting();
SqlHelper helper = new SqlHelper(setting.GetConnectionString("cn").Replace("Integrated Security=True", $"User ID={userName};pwd={password};Integrated Security=False"));
if (helper.HandShake())
{
setting.SaveConnectionString("conn", setting.GetConnectionString("cn").Replace("Integrated Security=True", $"User ID={userName};pwd={password};Integrated Security=False"));
helper = new SqlHelper(setting.GetConnectionString("conn"));
if (helper.HandShake())
{
_currentUser = userName;
if (_users == null && fillUsers)
{
FillUsers();
}
loginStatus = LoginStatus.Success;
}
else
{
loginStatus = LoginStatus.Failure;
}
}
else
{
loginStatus = LoginStatus.Failure;
}
});
progress.Report(loginStatus);
return loginStatus;
}