I'm using a loading screen in my winform application. So here I've
- main form (frmBilling)
- splashscreen form (frmsplash) and
- a class splashWorker.cs
This is the splashWorker.cs
public class splashWorker
{
public event EventHandler<splashWorkerEventArgs> ProgressChanged;
public event EventHandler HardWorkDone;
public void DoHardWork()
{
for (int i = 1; i <= 100; i++)
{
for (int j = 1; j <= 500000; j++)
{
Math.Pow(i, j);
}
this.OnProgressChanged(i);
}
this.OnHardWorkDone();
}
private void OnProgressChanged(int progress)
{
var handler = this.ProgressChanged;
if (handler != null)
{
handler(this, new splashWorkerEventArgs(progress));
}
}
private void OnHardWorkDone()
{
var handler = this.HardWorkDone;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
public class splashWorkerEventArgs: EventArgs
{
public splashWorkerEventArgs(int progress)
{
this.Progress = progress;
}
public int Progress
{
get;
private set;
}
}
and now, This is the code in splash screen.(There is a progressBar(progressBar1) in this form.)
public partial class frm_splash : Form
{
private delegate void ProgressDelegate(int progress);
private ProgressDelegate del;
public frm_splash()
{
InitializeComponent();
this.progressBar1.Maximum = 100;
del = this.UpdateProgressInternal;
}
private void UpdateProgressInternal(int progress)
{
if (this.Handle == null)
{
return;
}
this.progressBar1.Value = progress;
}
public void UpdateProgress(int progress)
{
this.Invoke(del, progress);
}
}
At last, this is the main form that I want to show after this splash screen loads.
public partial class frm_billingMain : Form
{
private frm_splash splashScreen;
private bool done = false;
public frm_billingMain(string get_uid)
{
InitializeComponent();
this.Load += new EventHandler(HandleFormLoad);
this.splashScreen = new frm_splash();
c.uid = get_uid;
}
private void HandleFormLoad(object sender, EventArgs e)
{
this.Hide();
Thread thread = new Thread(new ThreadStart(this.ShowSplashScreen));
thread.Start();
splashWorker worker = new splashWorker();
worker.ProgressChanged += (o, ex) =>
{
this.splashScreen.UpdateProgress(ex.Progress);
};
worker.HardWorkDone += (o, ex) =>
{
done = true;
this.Show();
};
worker.DoHardWork();
}
private void ShowSplashScreen()
{
splashScreen.Show();
while (!done)
{
Application.DoEvents();
}
splashScreen.Close();
this.splashScreen.Dispose();
}
What is happens is , when I run the form , I'm getting an exception :
InvalidOperationException was unhandled.
"Cross-thread operation not valid: Control 'frm_splash' accessed from a thread other than the thread it was created on."
This error was showing in ShowSplashScreen() in frm_Billingmain
private void ShowSplashScreen()
{
splashScreen.Show(); **//The exception is pointing here**
while (!done)
{
Application.DoEvents();
}
splashScreen.Close();
this.splashScreen.Dispose();
}
I tried a lot to solve and nothing happens well. Any help will be appreciated.
Thanks.