1

I am currently working on a project that requires processing a lot of data, so I decided to create a windows form informing the user that the processing is in progress. Of course I have to use another thread. But I need to run this windows form several times (not at the same time but it starts well the first time and not well the second), I must have a method that starts the thread and another that stops it as well as a label that will display different things depending on the number of loop perform in a method that is in another thread (it's tricky^^).

I read a lot about threads but I still have not found how to do it. Some code I did :

 public partial class Progress : Form
{

    Thread thr = null;

    public Progress()
    {
        InitializeComponent();
        try
        { 
             thr = new Thread(() => this.ShowDialog());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    public void Start()
    {
        thr.Start();           
        //this.ShowDialog();
    }

    public void Stop()
    {
        thr.Abort();
        thr.Join();
        //this.Close();
    }

and i want to use something liked that, How can I do it ?

other class {
  Progress t = new Progress();
  t.Start();
  firstFunction();
  SecondBigFunction(t);
  threeFunction();
  t.Stop();
}

SecondBigFunction(Thread t){
  while(list.lenght > 0){
    // Do somework
    t.labelToChange += 1;
  }
}

Thank you.

caraLinq
  • 71
  • 6

4 Answers4

4

You can use backgroundworker class in order to achieve your task

private BackgroundWorker bg1 = new BackgroundWorker();
 bg1.DoWork += bg1_DoWork;

 private void bg1_DoWork(object sender, DoWorkEventArgs e)
        {
           //the function you want to execute
        }

Similarly you can define various backgrounder workers with different functions in each one of them.

and finally call the background workers in the order in which you want the functions to be executed(all those functions will execute simultaneously).

hustlecoder
  • 187
  • 1
  • 1
  • 9
  • So i have to put showDialog() or the three Function() in private void bg1_DoWork(object sender, DoWorkEventArgs e) ? – caraLinq Nov 23 '17 at 08:58
  • If you put showDialog() in the DoWork(), then place the three functions in other backgrounworker. This will run the functions(one after another) and the dialog box will show(simultaneously.) – hustlecoder Nov 23 '17 at 09:04
3

I am not sure but it can helps you.

labeltoChange.Invoke((MethodInvoker)(() => labeltoChange.Text+=1));
CanFil
  • 335
  • 2
  • 8
  • Nice ! it works great but instead of getting 1 then 2 then 3 i get 1 then 11 then 111... – caraLinq Nov 23 '17 at 08:42
  • it's about adding 1 to text. you should set integer value and set it to text every time – CanFil Nov 23 '17 at 08:55
  • Okay, is it safe to do what i do ? with tread ant thr.abort(), because i see everywhere "Is not safe to use thread...olalala" ^^ – caraLinq Nov 23 '17 at 09:08
0

Normally all UI work should be performed on the same thread. So trying to launch a Form on a separate thread will normally just cause problems.

At the very least you would need to use Invoke, which will use the UI thread to update the control. So effectively means that you are just using one thread.

It is possible to do this, for more details you should see this; In WinForms, Is More than One Thread Possible in the UI?

and this; Multiple UI Threads - Winforms

Better practice is to put the "hard work" computations in a background worker thread, and then update the UI when you are finished.

This article gives an example; https://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners

jason.kaisersmith
  • 8,712
  • 3
  • 29
  • 51
0
labeltoChange.Invoke((MethodInvoker)(() => labeltoChange.Text+=1));

This method is a good way, it's just that when you do labeltoChange.Text+=1 you increment the number do not do addition.

If you want to add to the text box use this:

labeltoChange.Invoke((MethodInvoker)(() => Convert.ToInt32(labeltoChange.Text) + 1));
Barr J
  • 10,636
  • 1
  • 28
  • 46
  • 2
    Yeah but my label also have a text before and it's just at the end i add the number so i create an other label wich only have the number and i do this recherche += 1; t.lblNbRecherche.Invoke((MethodInvoker)(() => t.lblNbRecherche.Text = recherche.ToString())); thank you – caraLinq Nov 23 '17 at 09:11