如何修复错误:从不同的线程访问了“dataGridView1”控件[重复]
Posted
技术标签:
【中文标题】如何修复错误:从不同的线程访问了“dataGridView1”控件[重复]【英文标题】:How to fix the error: the 'dataGridView1' control was accessed from a different thread [duplicate] 【发布时间】:2021-10-04 10:16:41 【问题描述】:大家早上好,我在重写 DataGrid 时遇到了麻烦,该函数可以工作,但我需要进行更快的搜索,所以我的想法是添加并行性。
但在应用后者时,它会为我生成一个错误:System.InvalidOperationException:'无效的跨线程操作:控件'dataGridView1'是从与执行创建的线程不同的线程访问的。'
问题对我来说很清楚,但是我不知道如何解决它。各位大神能帮帮我吗?
我已经尝试过调用 Invoke,但程序进入了无限循环。
private void inputSearch_TextChanged(object sender, EventArgs e)
Parallel.For(0, 7, i =>
Ricerca(i);
);
private void Ricerca(int i)
string searchValue = inputSearch.Text.ToUpper();
var re = from row in dataTable.AsEnumerable()
where
row[i].ToString().Contains(searchValue)
select row;
if (re.Count() != 0)
Invoke(new Action(() =>
dataGridView1.DataSource = re.CopyToDataTable();
dataGridView1.Columns[7].Visible = false;
));
【问题讨论】:
不要直接从另一个线程访问DataGrid
。仅从您的 UI 线程访问您的 UI。如果您有要并行执行的计算,请将其结果存储在其他地方并使用 UI 线程读取这些结果,并在您的工作人员完成后将它们应用到 UI。还有一些方法可以将部分执行“委托”到 UI 线程中,但这有一些警告,请查看SynchronizationContext
(更深入的here)。
无限循环与第一个问题有什么关系吗?看起来您使用调用解决了一个问题,现在您遇到了第二个问题。
【参考方案1】:
您遇到了死锁,因为您在 inputSearch_TextChanged
方法(由 UI 线程调用)中阻塞了 UI 线程。
如果您的意图是并行化 Linq
表达式,请将 Ricerca
方法一分为二。该方法的最后一部分应该在并行之外调用,可能直接在inputSearch_TextChanged
上调用。
更好的解决方案可能是改用 .NET Task。
否则,如果你根本不需要并行,你可以用一个简单的for
替换它。
【讨论】:
【参考方案2】:我能够按照 Cherry 的建议通过将内容保存在另一个表中并稍后重新复制来解决问题。
private void inputSearch_TextChanged(object sender, EventArgs e)
Parallel.For(0, 7, i =>
Ricerca(i);
);
dataGridView1.DataSource = table;
dataGridView1.Columns[7].Visible = false;
private void Ricerca(int i)
string searchValue = inputSearch.Text.ToUpper();
var re = from row in dataTable.AsEnumerable()
where
row[i].ToString().Contains(searchValue)
select row;
if (re.Count() != 0)
table = re.CopyToDataTable();
谢谢大家!
【讨论】:
以上是关于如何修复错误:从不同的线程访问了“dataGridView1”控件[重复]的主要内容,如果未能解决你的问题,请参考以下文章
“调用线程无法访问此对象,因为不同的线程拥有它”从 WPF 中的不同线程更新 UI 控件时出现错误
如何修复“线程 1:致命错误:在展开可选值时意外发现 nil”错误? [复制]
如何修复访问被拒绝路径错误asp.net应用程序访问网络共享