I have a splashscreen:
public partial class LoadingScreen : Form
{
private delegate void CloseDelegate();
private static LoadingScreen loadingscreen;
private LoadingScreen()
{
InitializeComponent();
}
private static void ShowForm()
{
loadingscreen = new LoadingScreen();
Application.Run(loadingscreen);
}
public static void ShowLoadingscreen()
{
if (loadingscreen != null)
return;
System.Threading.Thread thread = new System.Threading.Thread(LoadingScreen.ShowForm);
thread.IsBackground = true;
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.Start();
}
public static void CloseForm()
{
loadingscreen.Invoke(new CloseDelegate(LoadingScreen.CloseFormInternal));
}
private static void CloseFormInternal()
{
loadingscreen.Close();
loadingscreen = null;
}
}
It is called whene the datagrid is busy to refresh (it need some drawing and it takes a while for our hugh data) also whene the user uses the textbox to search something it's triggerd because we need to redraw everything. The code what triggerd the splashscreen:
private void EditGrid()
{
LoadingScreen.ShowLoadingscreen();
CheckItems();
EditGridVisibility();
LoadingScreen.CloseForm();
}
when the user types in 3, 4, or 5 characters in the searchbox I get a NullReferenceException on the LoadingScreen.CloseForm();
And it's correct I get a NullRef, because I don't see the form in debugging so there goes something wrong when showing (or closing the last time) but I don't see why.
This error occurs when CloseForm is called before ShowLoadingScreen has had time to spin up it's thread and create loadingScreen.
It is almost always easier to load/process the data on a background thread and display dialogs on your main UI thread. But if that is not possible, ensure the dialog is displayed before dismissing it or abort its creation.
A rough solution would be to make the thread global and...
public static void CloseForm()
{
if (loadingscreen == null)
{
_thread.Abort();
return;
}
loadingscreen.Invoke(new CloseDelegate(CloseFormInternal));
}