请建议我如何在这里使用多线程它只是一个例子..请解释任何其他方式..
解决方案这段代码有几个问题。
您正在从工作线程访问 DataGridView 。在检查中的第一行代码显而易见。你不能这样做。
你定义了变量 i , j , l ,大概 k 和 m (虽然我没有看到他们在任何地方声明)为静态。结果是,每个工作线程将使用相同的值并且相互对齐的脚趾。对于 i 来说,这是一个更大的问题,因为它实际上是从工作线程访问的。其他人从匿名代理访问,该代理被封送到UI线程上。但是,这可能会导致很多混乱,因为匿名代理执行的顺序是不可预测的。
您正在调用从工作线程调用。这本身不是问题。但是,考虑到您将所有有用的工作整理到UI线程上是没有意义的。想想吧你去所有的工作,使用工作线程,然后你把所有的东西回到UI线程无论如何。你现在有一个比你没有使用任何工作线程更糟的解决方案。
这不是一个问题,但更多的是我有。为什么打扰调用 InvokeRequired ?你已经知道调用是必需的,因为你在开发时知道这些东西在工作线程上。
我的建议如下。
根本不要使用线程。在这种情况下是毫无意义的。可以在另一个线程上执行的唯一有用的工作是比较名字和姓氏。这是微不足道的,可以在UI线程上快速完成。
如果你真的想使用一个单独的线程,那么你从UI线程上的 DataGridView 中读取值,并将它们放在单独的数据结构中;一个可以从另一个线程使用的。当您开始长时间运行的时候,您将不需要阅读网格,因此您可以通过 DataGridView 来保持此数据结构。将数据复制到这个单独的数据结构中。
Here i'm doing one process of checking user names. I've created one datagridview and loadded data from the text file. so the datagridview contains first name and last name of users in first two columns . What i need to do is read those values row by row and find that there is no same name for first and last .These operation is performed in separate class. So i need to get result from that class and show the result to gridview alternatively . It all works fine when i'm using just one thread . But when i'm using more than one thread it just throwing an exception that outofbound exception in gridview reading . Here is my coding :
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(); } }Please suggest me how to use Multithread here ... its just an example .. please explain any other way ..
解决方案There are several problems with this code.
You are accessing the DataGridView from a worker thread. This is evident by the first line of code in check. You simply cannot do this.
You defined the variables i, j, l, and presumably k and m (though I do not see them declared anywhere) as static. The consequence is that each worker thread will be working with the same values and stepping on each other's toes. It is a bigger problem for i since it actually is being accessed from the worker thread. The others are accessed from anonymous delegate which is marshaled onto the UI thread. Still, that is probably going to cause a lot of confusion because the order in which anonymous delegates are getting executed is unpredictable.
You are calling Invoke from the worker thread. This is not a problem by itself. But, considering that you are mashaling all of the useful work back onto the UI thread it is rather pointless. Think about it. You went to all that work to use a worker thread and then you marshal everything back onto the UI thread anyway. You now have a solution that is worse than had you not used any worker threads at all.
This is not a problem really, but more of a gripe I have. Why bother calling InvokeRequired? You already know that "invoking" is required because you know at development time that this stuff is on a worker thread.
My recommendations are as follows.
Do not use threads at all. It is pointless in this case. The only useful work that can be performed on a another thread is the comparison of the first and last names. That is trivial and can be done just as quickly on the UI thread.
If you really want to use a separate thread then you have to read the values from the DataGridView on the UI thread and put them in a separate data structure; one that is safe to use from another thread. It would be better to maintain this data structure in tandem with the DataGridView that way when it comes time to initiate your long running operation you will not need to read the grid since you already have the data copied into this separate data structure.
更多推荐
Datagridview C#的多线程
发布评论