使用 Datagridview C# 进行多线程处理

2024-03-10

这里我正在做一个检查用户名的过程。我创建了一个 datagridview 并从文本文件加载了数据。因此 datagridview 在前两列中包含用户的名字和姓氏。我需要做的是逐行读取这些值,并发现第一个和最后一个没有相同的名称。这些操作是在单独的类中执行的。所以我需要从该类获取结果并将结果显示给 gridview 。当我只使用一个线程时,一切正常。但是,当我使用多个线程时,它只会抛出一个异常,即 gridview 读取中的 outofbound 异常。这是我的编码:

static int i, j=0, l=0,k=0,m=0;

public void check()
{ 
    for (i = 0; i < dataGridView1.Rows.Count ; i++)
    {
        if (InvokeRequired)
        {
            Invoke(new UpdateDelegate(delegate
                {
                    if (i == 0 && j==0)
                    {
                        DataGridViewColumn col = new DataGridViewTextBoxColumn();
                        col.HeaderText = "Status";
                        int colIndex = dataGridView1.Columns.Add(col);
                        dataGridView1.Rows[i].Cells[colIndex].Value = "Process Started";
                        j = 1;
                    }
                    else
                    {
                        dataGridView1.Rows[i].Cells[3].Value = "process Started";            
                    }
                }));
        }

        if (InvokeRequired)
        {
            Invoke(new UpdateDelegate(delegate 
                { 
                    Process obj_reg = new Process(dataGridView1.Rows[i].Cells[1].Value.ToString(),dataGridView1.Rows[i].Cells[2].Value.ToString());
                    string res = obj_reg.register();
                    Thread.Sleep(500);
                    if (res.Contains("success"))
                    {
                        if (i == 0 && k==0)
                        {
                            DataGridViewColumn col = new DataGridViewTextBoxColumn();
                            col.HeaderText = "Result";
                            int colIndex = dataGridView1.Columns.Add(col);
                            dataGridView1.Rows[i].Cells[colIndex].Value = "Ya its different";
                            dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Green;
                            k = 1;
                        }
                        else 
                        {
                            dataGridView1.Rows[i].Cells[4].Value = "Ya its different";                              
                            dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Green;
                        }
                    }
                    else
                    {
                        if (i == 0 && m == 0)
                        {
                            DataGridViewColumn col = new DataGridViewTextBoxColumn();
                            col.HeaderText = "Result";
                            int colIndex = dataGridView1.Columns.Add(col);
                            dataGridView1.Rows[i].Cells[colIndex].Value = "No its same";
                            dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Red;
                            m = 1;
                        }
                        else
                        {
                            dataGridView1.Rows[i].Cells[4].Value = "No its same";
                            dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Red;

                        }
                    }
                }));
        }
    }
}

public void Button1_Click(Object sender, EventArgs e)
{
    Thread[] threads = new Thread[3];
    for (int l = 0; l < 3; l++)
    {
        threads[l] = new Thread(new ThreadStart(check));
    }
    foreach (Thread t in threads)
    {
        t.Start();
    }
}

请建议我如何在这里使用多线程...这只是一个例子..请解释任何其他方式..


这段代码有几个问题。

  1. 您正在访问DataGridView来自工作线程。从第一行代码可以明显看出这一点check。你根本无法做到这一点。

  2. 您定义了变量i, j, l,并且大概k and m(尽管我没有看到它们在任何地方声明)为静态的。结果是每个工作线程都将使用相同的值并互相干扰。这是一个更大的问题i因为它实际上是从工作线程访问的。其他的可以从编组到 UI 线程上的匿名委托进行访问。尽管如此,这可能会引起很多混乱,因为匿名委托的执行顺序是不可预测的。

  3. 你正在呼唤Invoke来自工作线程。这本身并不是问题。但是,考虑到您将所有有用的工作重新整合到 UI 线程上,这是毫无意义的。想一想。您完成了所有工作以使用工作线程,然后将所有内容封送回 UI 线程。现在您有了一个比根本不使用任何工作线程更糟糕的解决方案。

  4. 这实际上不是一个问题,但更多的是我的抱怨。何必打电话麻烦InvokeRequired?您已经知道“调用”是必需的,因为您在开发时知道这些东西位于工作线程上。

我的建议如下。

  1. 根本不要使用线程。在这种情况下这是没有意义的。可以在另一个线程上执行的唯一有用的工作是比较名字和姓氏。这很简单,并且可以在 UI 线程上同样快速地完成。

  2. 如果你真的想使用单独的线程那么你have读取值DataGridView在UI线程上并将它们放在单独的数据结构中;可以从另一个线程安全使用的一个。最好将这个数据结构与DataGridView这样,当需要启动长时间运行的操作时,您将不需要读取网格,因为您已经将数据复制到这个单独的数据结构中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Datagridview C# 进行多线程处理 的相关文章

随机推荐

  • 如何在 Android NDK 中创建新的 NativeWindow?

    我尝试了 test libstdc 演示 并且喜欢我可以从控制台启动它 而无需运行成熟的 Android 应用程序 我想创建一个 opengl 上下文 以便我能够从控制台内执行我的 opengl es 2 0 应用程序 而无需太多麻烦 知道
  • Distutils:构建多个共享方法的 Python 扩展模块(用 Swig 编写)

    我有四个 C 文件 A h A cpp B h B cpp A h 包含在 B cpp 中 A h pragma once void A A cpp include
  • 以编程方式创建选择列表

    有谁知道使用 JQuery 以编程方式创建包含选项的 HTML 选择列表的技术 var arr val 1 text One val 2 text Two val 3 text Three var sel
  • Redis serviceStack池化连接客户端

    我正在设计一个使用 Redis 作为数据库的 Web 服务 我想了解使用 Redis 与 StackService 客户端连接的最佳实践 重点是 我一直在阅读有关 Redis 的内容 并且发现与服务器交互的最佳方式是使用单个并发连接 问题是
  • 使用 Firebase 进行数据库式查询

    有没有一种快速的方法可以使用 Firebase 执行数据库式查询 例如 给出 firebase 参考users有字段user id name and age 执行与此类似的查询的最佳方法是什么 SELECT name FROM users
  • 如何处理原始数据(用Python)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我没有很好地解释这一点 所以希望这个编辑更有意义 基本上我必须编写适用于大量测试用例的代码 下面的输入只是一个示例 所以我无法手动将输入输
  • Angular 2 - 当(observableData | async)尚未解析时显示加载信息

    正如标题所说 我想拥抱 rxjs Observables 的力量 我现在应该做什么 dataview html div Loading data div gt ul li d value li ul dataview ts data any
  • AutoFixture 2 With() 无法像 AutoFixture 1 中那样工作?

    我正在将我的测试移植到自动夹具2 0 http autofixture codeplex com 我遇到了一些奇怪的行为 我既无法解释也无法修复 这个简单的测试对我来说失败了 var autoFixtures new Fixture var
  • Silverlight 控件由于命令而未被垃圾回收

    我的控制之所以能保持活力 是因为它必须服从命令 我怎样才能打破这个参考 这导致我的应用程序中出现严重的内存泄漏 该控件位于 DataTemplate 内部 因此我无法直接访问它 这是我的 ANTS 内存配置文件 我到底该如何断开这种连接 虽
  • 有没有办法通过为每个测试打开浏览器实例来并行运行量角器测试?

    我的量角器测试面临同步问题 我想与我的实际设置相比并行运行我的测试 事实上 目前我的测试一个接一个地运行 我知道如何使用 TestsNG 执行此操作 但不确定如何使用 Jasmin Framework 执行此操作 要在两个浏览器之间分配测试
  • IDEA Groovy 测试类已经存在

    IDEA 向我的 groovy 类发出警告 类 MyClassTest 已存在于 my class package 中 当我运行测试时 它似乎也没有很好地保持类的更新 我将添加一个保证失败或成功的断言 直到稍后它才会识别它 到目前为止似乎是
  • 确定 Java 中的有效日期

    我有一个家庭作业 要求用户以 mm dd yyyy 格式在 Java 中输入日期 然后确定输入的日期是否有效 我已经能够成功地对每个月 除了二月 执行此操作 因为您必须考虑闰年 我有这个代码 import java util Scanner
  • 使用 WPF 将二进制文件检索回图像和数据库并保存到文件夹中

    我已成功将图像转换为二进制并使用 linq to sql WPF 将其保存到数据库中 现在我想将其检索回图像格式并将其保存到计算机中的特定文件夹中 我读过很多博客和文章 它们从数据库检索图像二进制文件 然后将其显示到 PictureBox
  • 如何在Python中正确编码json转储[重复]

    这个问题在这里已经有答案了 我有一个 python 3 脚本 应该从 csv 文件获取一些数据并将其写入 json 文件 在我的处理过程中 编码是正确的 因此德语变音 或度数符号 就像它们本来的样子 coding cp1252 在头部 但是
  • 使用布尔索引复制或查看 numpy 子数组

    给定一个 2D numpy 数组 即 import numpy as np data np array 11 12 13 21 22 23 31 32 33 41 42 43 我需要创建一个新的子数组 或者根据所需行和列的两个掩码向量修改选
  • 在 Python ConfigParser 中按字母顺序导出

    是否有任何解决方案可以强制 RawConfigParser write 方法按字母顺序导出配置文件 即使原始 加载的配置文件已排序 模块也会任意地将节和选项混合到节中 并且手动编辑巨大的未排序配置文件确实很烦人 PD 我正在使用 pytho
  • 为什么 WriteResultChecking 默认设置为 NONE?

    根据Spring Data MongoDB 文档 http docs spring io spring data mongodb docs current reference html mongo template writeresultc
  • 在 TFS 2012 中运行 Jasmine 的 Chutzpah 找不到测试中的引用文件

    我正在使用 Chutzpah 来运行我们的 Jasmine 测试 我已将 Chutzpah dll 添加到解决方案中 并更新了构建以运行 js 测试 项目结构如下 MyApp Web Scripts App Home DateControl
  • AVPlayer播放ts文件

    我想从服务器播放 ts 文件 void play NSURL url NSURL URLWithString http 10 0 0 18 11 ts player AVPlayer alloc initWithURL url player
  • 使用 Datagridview C# 进行多线程处理

    这里我正在做一个检查用户名的过程 我创建了一个 datagridview 并从文本文件加载了数据 因此 datagridview 在前两列中包含用户的名字和姓氏 我需要做的是逐行读取这些值 并发现第一个和最后一个没有相同的名称 这些操作是在