【问题标题】:Use threads with windows form c#在 Windows 窗体 c# 中使用线程
【发布时间】:2015-09-16 18:47:04
【问题描述】:

我想在我的 windows 窗体中的一些函数中使用线程。

我有一个按钮,可以添加并检查输入是否正确,超过 4k 个项目按顺序到我的表单中的列表视图,但表单冻结,直到它过度执行函数,然后所有项目立即出现。 我想知道如何在不冻结表单的情况下查看使用线程逐个添加的项目。我阅读了有关线程和后台工作者(https://msdn.microsoft.com/pt-br/library/ms171728(v=VS.110).aspx)的信息,但我不太了解如何将函数与后台链接工人,或如何安全地调用线程(与委托部分混淆)。 以及如何让它在线程完成后调用一个函数?

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

【问题讨论】:

  • 可以看下面System.Diagnostics.ProcessWindowStyle.Hidden

标签: c# multithreading winforms


【解决方案1】:

如果您希望您的 UI 具有响应性,您需要使用 BackgroundWorker。在这里你有一个关于它的文档http://www.albahari.com/threading/part3.aspx#_BackgroundWorker

另一个问题是一个函数,我想通过调用多个线程来更快地执行,这个不需要按顺序排列。它也来自一个按钮:

然后您可以再次使用并行库。 Parallel.Foreach 方法将有助于实现您的目标。在这里你有相同的链接http://www.albahari.com/threading/part5.aspx#_Parallel.For_and_Parallel.ForEach

【讨论】:

  • 它给出了 invalidOperarionException
  • @kadzu 如果你说BackgroundWorker 有问题,它不这么认为。如果您说我的代码不起作用,那么您应该发布您与 BackgroundWorker 一起使用的代码以及您在何处获得此异常。我们不是魔术师……
  • 您阅读我复制的链接了吗?如果你感到困惑,有一个例子。当然,您需要先了解委托才能使用它。 BackgroundWorker 使用一个委托调用具有以下签名 YourMethod (object sender, DoWorkEventArgs e) 的方法,我认为这是您需要的链接,因此您可以订阅该事件 backgroundworker.DoWork += YourMethod 然后您可以开始backgroundworker.RunWorkerAsync(yourparam)
【解决方案2】:

要隐藏控制台窗口,请查看此可能的重复项:

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

对于线程,您需要控制线程数以避免机器泛滥。考虑使用Thread Pool

如果您使用的是 .Net 4.0+,PLinQ 将通过并行 for 循环优雅地完成这项工作。 Options here.

【讨论】:

    猜你喜欢
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多