0

I would like to use thread in a few functions in my windows form.

I have a button that would add and check if the input was correct over 4k items in order to the listview in my form, but the form freezes until its over executing the function and then all the items show up at once. I would like to know how can I see the items being added one by one using threads without the form freezing.I read about threads and background worker(https://msdn.microsoft.com/pt-br/library/ms171728(v=VS.110).aspx) but I didnt understand it very well how to link a function with the background worker,or how to call the thread safely(got confused with delegate part). And how can I make it call a function after the thread is done?

This is what I'm trying but its giving "InvalidOperationException" at 2 places: 

 - when I try to add the item to my listView at
   "lissView1.Items.Add(tempItem)" in the of "bw1_DoWork" loop.


 - When I try "String temp = ..." inside the "Parallel.For":






    namespace WindowsFormsApplication2
    {




public partial class mainForm : Form
    {
    private BackgroundWorker bw1;

    public mainForm()
        {
            InitializeComponent();
            formLoad();
            bw1 = new BackgroundWorker();
            bw1.DoWork += bw1_DoWork;
        }

    private void pasteButton_Click(object sender, EventArgs e)
        {
         bw1.RunWorkerAsync(Clipboard.GetText());
    }   


    private void bw1_DoWork(object sender, DoWorkEventArgs e){
        String temp = "";
            int n;
            ListViewItem.ListViewSubItem tempSubItem;
            ListViewItem tempItem;
        String cp =(String) e.Argument;
            string[] stringSeparators = new string[] { "\r\n" };
            string[] rows = cp.Split(stringSeparators, StringSplitOptions.None);
            for (int i = 0; i < rows.Length-1; i++)
            {
                tempItem = new ListViewItem(rows[i].Split('\t'));
                tempItem.UseItemStyleForSubItems = false;

                tempSubItem = new ListViewItem.ListViewSubItem();
                tempSubItem.BackColor = Color.Green;
                tempSubItem.Text = "NORMAL";
                temp = String.Format("{0}\\{1}", TextBox0.Text, tempItem.SubItems[1].Text);
                if (!File.Exists(temp))
                {
                    tempItem.SubItems[1].BackColor = Color.Red;
                    tempSubItem.BackColor = Color.Red;
                    tempSubItem.Text = "ERRO";
                }
                temp = String.Format("{0}\\{1}", TextBox1.Text, tempItem.SubItems[2].Text);
                if (!File.Exists(temp))
                {
                    tempItem.SubItems[2].BackColor = Color.Red;
                    tempSubItem.BackColor = Color.Red;
                    tempSubItem.Text = "ERRO";
                }
                if (int.TryParse(tempItem.SubItems[0].Text, out n))
                {
                    if (n > networkList.Items.Count)
                    {
                        tempItem.SubItems[0].BackColor = Color.Red;
                        tempSubItem.BackColor = Color.Red;
                        tempSubItem.Text = "ERRO";
                    }
                }
                else
                {
                    tempItem.SubItems[0].BackColor = Color.Red;
                    tempSubItem.BackColor = Color.Red;
                    tempSubItem.Text = "ERRO";
                }
                try
                {
                    tempItem.SubItems[4] = tempSubItem;
                }
                catch (ArgumentOutOfRangeException)
                {
                    tempItem.SubItems.Add(tempSubItem);
                }

                lissView1.Items.Add(tempItem);
            }
        }

    private void interactiveRunButton_Click(object sender, EventArgs e) 
    {
         ParallelOptions options = new ParallelOptions();
            options.MaxDegreeOfParallelism = 4;
            Parallel.For(0, inputList.Items.Count,
                   index =>
                   {
                       testex(String.Format("{0};{1};{2};{3}", listView1.Items[index].SubItems[0].Text, listView1.Items[index].SubItems[1].Text, listView1.Items[index].SubItems[2].Text, listView1.Items[index].SubItems[3].Text));
                   });
    }
    static void testex(string f)
    {
        Process compiler = new Process();
            compiler.StartInfo.FileName = "testex.exe";
            compiler.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            compiler.StartInfo.Arguments =f;
            compiler.StartInfo.UseShellExecute = false;
            compiler.StartInfo.RedirectStandardOutput = true;
            compiler.Start();
            Console.WriteLine(compiler.StandardOutput.ReadToEnd());
    }
    }
}
Carlos Siestrup
  • 1,031
  • 2
  • 13
  • 33

2 Answers2

1

You need to user BackgroundWorker if you want that your UI will be responsive. Here you have a documentation about it http://www.albahari.com/threading/part3.aspx#_BackgroundWorker

Another problem is a function that I would like to execute faster by calling more than 1 thread, this one doesnt need to be in order. Its also from a button:

Then again you can use Parallel library. Parallel.Foreach method will be usefull to achive your goal. Here you have the same link http://www.albahari.com/threading/part5.aspx#_Parallel.For_and_Parallel.ForEach

Zinov
  • 3,817
  • 5
  • 36
  • 70
  • Its giving invalidOperarionException – Carlos Siestrup Sep 16 '15 at 19:34
  • 1
    @kadzu if you say `BackgroundWorker` is buggy, it don't think so. If you say *my code doesn't work*, then you should post the code you used with BackgroundWorker and where you get this exception. We are not magicians.... – Eser Sep 16 '15 at 19:41
  • Did you read the link that I copied? There is an example in case you are confuse. You need to understand delegate first to use it of course. BackgroundWorker use a delegate that invokes a method with the following signature YourMethod (object sender, DoWorkEventArgs e) , I think that this is the link that you need, so you can subscribe to that event backgroundworker.DoWork += YourMethod and then you can start backgroundworker.RunWorkerAsync(yourparam) – Zinov Sep 16 '15 at 22:34
0

For hiding the console window, look in to this possible duplicate:

.Net Console Application that Doesn't Bring up a Console

For threading you will need to control the number of threads in order to avoid flooding your machine. Consider using the Thread Pool

If you are using .Net 4.0+, PLinQ will do the job elegantly with a parallel for loop. Options here.

Community
  • 1
  • 1
Murray Foxcroft
  • 12,785
  • 7
  • 58
  • 86