Carlos Siestrup
Carlos Siestrup

Reputation: 1216

Use threads with windows form c#

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());
    }
    }
}

Upvotes: 0

Views: 781

Answers (2)

Murray Foxcroft
Murray Foxcroft

Reputation: 13795

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.

Upvotes: 0

Zinov
Zinov

Reputation: 4119

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

Upvotes: 1

Related Questions