0

I'm having some issues while waiting for a ThreadState during the Click event of a button control. Whenever I click my button it'll execute the code below. The problem with this is that it won't wait until the ThreadState is "Stopped", so it never enables btnImportData or btnExportBellijst.

I've tried t.Join() but that freezes my whole form and I use a RichTextBox as logger, so that'd result in a logger that freezes for a few seconds and then shows a lot of text at once. The reason I put the ImportData function on another Thread is to keep the form running so people can see the logs happening realtime.

What I'd like to have when I click my button:

  1. Change Enabled of 1 or more buttons.
  2. Run my function ImportData on another thread so my logger can keep logging. (void ImportData(){})
  3. Change Enabled of 1 or more buttons after my function is done doing something.

    private void btnImportData_Click(object sender, EventArgs e)
    {
        //Disable current button
        btnImportData.Enabled = false;
        imgBonne.Visible = false; //random image
        rtConsole.Visible = true; //RichTextBox logger
    
        //Create a new thread for the button function    
        var t = new Thread(ImportData);
        t.Start();
    
        //It does NOT wait until thread stopped
        while (t.ThreadState == ThreadState.Stopped)
        {
            //Never gets executed
            btnImportData.Enabled = true;
            btnExportBellijst.Enabled = true;
        }
    }
    

Extra Info: Screenshot from before pressing "Import Data": http://puu.sh/88oD6.png Screenshot from after the application is done importing data: http://puu.sh/88oNT.png

(edit)Target framework: .NET Framework 4

I was originally using the code below, but this instantly enables all the buttons after pressing "Import Data".

    private void btnImportData_Click(object sender, EventArgs e)
    {
        imgBonne.Visible = false; //random image
        rtConsole.Visible = true; //RichTextBox logger

        var t = new Thread(ImportData);
        t.Start();

        while (t.ThreadState == ThreadState.Running)
        {
            btnImportData.Enabled = false;
        }
        btnImportData.Enabled = true;
        btnExportBellijst.Enabled = true;
    }

Edit: I'm sorry if this is in the wrong category, I wanted to put it in c#.

  • 1
    This may help http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net – Bit Apr 14 '14 at 15:03

1 Answers1

1

Using the Task Parallel Library can make it a whole lot easier:

private void btnImportData_Click(object sender, EventArgs e)
    {
        imgBonne.Visible = false; //random image
        rtConsole.Visible = true; //RichTextBox logger

        btnImportData.Enabled = false;

        Task.Run(ImportData).ContinueWith((Task task) =>
        {
            btnImportData.Enabled = true;
            btnExportBellijst.Enabled = true;
        }, TaskScheduler.FromCurrentSynchronizationContext());
    }
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • thank you! However I apologize as I forgot to mention that I was using .NET Framework 4. I have changed Task.Run to Task.Factory.StartNew, but I can't seem to figure out how to get ContinueWith to work :s –  Apr 14 '14 at 19:16
  • What isn't working? The continuation isnt executing? – Yuval Itzchakov Apr 14 '14 at 20:00
  • I'm getting an error when compiling: "Delegate 'System.Action' does not take 0 arguments" after replacing "Task.Run" with "Task.Factory.StartNew". (screenshot: http://puu.sh/88Lxd.png The green lines are from resharper, they're not an error, just a suggestion) Edit: http://puu.sh/88LOh.png when hovering over the red lines it shows that. –  Apr 14 '14 at 20:21
  • Try ContinueWith((Task task) => {code here}). Edited my answer – Yuval Itzchakov Apr 15 '14 at 07:09