c# - 跨线程异常 - 仅限环境

标签 c# winforms multithreading marshalling

控件只能由创建它的线程访问——我知道的就这么多。

  1. 我有一个带有 基于 BindingList<> 的数据源。
  2. 我有一个工作线程(非 GUI) 有点花哨 计算/比较/等和 然后在 BindingList<> 中添加/编辑一个对象。
  3. 在计时器上,GUI 线程根据 BindingList<> 刷新自身。

只要我不在环境中运行,这段代码就可以完美运行。在 BindingList<> 上调用 .Add() 方法的环境中,我得到了这个方便的小错误:

An Exception has occurred
EXCEPTION : Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.
IN METHOD : get_Handle
AT LINE   : 0
CLASS     : System.Windows.Forms.Control

请注意被违反的控件的名称​​是空白的...我认为如果问题出在更新 BindingList<> 上,那么如果我在环境中运行则无关紧要或不。尽管如此,这就是我所看到的。 此外,即使抛出异常,.Add() 也会成功完成!!

显然,这在我的生产环境中不是什么大问题(现在?),因为它只发生在 Studio 中; 是的,我可以调用 GUI 线程来执行添加,或者将添加的内容存储在一个地方,以便 GUI 线程稍后检索它们……我不是在寻找解决方法,而是在寻找更多所以我对这个问题的答案很感兴趣:

为什么只有studio出现错误?

最佳答案

如果是 MDA (Managed Debugging Assistant),则该错误可能仅在 VS 中发生,而不是运行时异常。 MDA 会告诉你什么时候你正在做一些通常但不是 100% 总是会在生产代码中给你带来麻烦的事情(这最终会,即使它似乎 99% 的时间都在工作你的机器)。

您应该调用 UI 线程来执行 Add 方法。

编辑:要 100% 彻底......没有 Reflector(因为我的过期了 - 你在听 Red Gate 吗?!)我猜测 Control 类检查你是否在 UI 线程上,抛出异常后台线程,如果你不是,然后重绘用户界面。由于后台线程已经添加了该项目,UI 重绘看到它并按预期将其绘制到 UI,但是您的后台线程仍然看到异常,您要么在 catch block 中默默地吞下它,要么后台线程是被终止(这在您的应用程序中可能是可以容忍的,例如,BG 线程是一个线程池线程)。

关于c# - 跨线程异常 - 仅限环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6206622/

相关文章:

C# 不能在 ushort 列表项中使用 Linq DefaultIfEmpty?

c# - 如何配置 C# 程序在操作系统首次启动时运行?

c# - 使用 C# 和 wpf 创建一个类似应用程序的停靠点

android Volley,RequestQueue中的cancelAll和stop方法有什么区别

c# - 锁定文件创建的最佳方式(最佳性能)

c# - 在 .NET 中使用 DjVu

c# - Visual Studio 自动删除未被引用的方法的工具

c# - 一个存储过程也可以更新整个表或单个列

.net - 如何删除标签控件中的填充?

c++ - 基本的 C++ 多线程