5

I'm using a thread to run a calculation in the background of my program. I start the thread at the start of my program. If I press a button before the thread is finished it will open the statusBar and "openedStatus" is set to true.

This will show the threads current progress and after the thread has finished I would like to execute the last part of my code:

if (openedStatus)
{
    sb.Close();
    validateBeforeSave();
}

This part of the code will throw an exception though because you can't close the statusbar cross-thread.

Now the question is: How can I execute that last part of the code after the thread is finished?

private StatusBar sb = new StatusBar();
private void startVoorraadCalculationThread()
{
    sb.setMaxProgress(data.getProducten().getProductenCopy().Count);
    Thread thread = new Thread(new ThreadStart(this.run));
    thread.Start();
    while (!thread.IsAlive) ;
}

private void run()
{
    for (int i = 0; i < data.getProducten().getProductenCopy().Count; i++ )
    {
        sb.setProgress(i);
        sb.setStatus("Calculating Voorraad: " + (i+1) + "/" + data.getProducten().getProductenCopy().Count);
        data.getProducten().getProductenCopy()[i].getTotaalVoorraad(data.getMaten());
    }
    if (openedStatus)
    {
        sb.Close();
        validateBeforeSave();
    }
    calculationFinished = true;
}
Duckdoom5
  • 716
  • 7
  • 27
  • move the last part back to your main thread? and why not just use a backgroundworker? – Bolu Oct 07 '13 at 11:18
  • Yeah, but if I move that last part back, there is no way to check if the thread has finished executing, is there? And I'll look into the backgroundworker, thanks. – Duckdoom5 Oct 07 '13 at 11:21
  • I think `Thread.IsAlive` will show you if the thread is finished/aborted. but still, `BackgroundWorker` is easier – Bolu Oct 07 '13 at 11:25
  • Hmm, well, then I still have one problem because then I would have to use a while loop to constanly check if the thread is alive, so thats not realy a great sollution. – Duckdoom5 Oct 07 '13 at 11:28
  • On the microsoft website it tells me that the BackgroundWorker is part of Silverlight, if so, can I use it if silverlight is not installed? Source: http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx – Duckdoom5 Oct 07 '13 at 11:30
  • its with the .net framework (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.100).aspx), so it's not only for `silverlight`, so you put your for loop into the `DoWork` event handler and the last bit into the `RunWorkerCompleted` handler. and if you are still interested in how to check if a thread is finished, here is a good answer:http://stackoverflow.com/a/2228508/352101 – Bolu Oct 07 '13 at 11:32
  • It seems like the background worker is indeed a better sollution, so thanks for your help. – Duckdoom5 Oct 07 '13 at 11:37

1 Answers1

4

Using a backgroundWorker fixed my problem:

private void startVoorraadCalculationThread()
{
    sb.setMaxProgress(data.getProducten().getProductenCopy().Count);

    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

    bw.RunWorkerAsync();
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < data.getProducten().getProductenCopy().Count; i++)
    {
        sb.setProgress(i);
        sb.setStatus("Calculating Voorraad: " + (i + 1) + "/" + data.getProducten().getProductenCopy().Count);
        data.getProducten().getProductenCopy()[i].getTotaalVoorraad(data.getMaten());
    }
}

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (openedStatus)
    {
        sb.Close();
        validateBeforeSave();
    }
    calculationFinished = true;
}
Duckdoom5
  • 716
  • 7
  • 27