c# - 需要对线程中创建的对象的生命周期进行解释

标签 c# winforms multithreading object-lifetime

我有一个绑定(bind)到 BindingList 的 DevExpress GridControl。

我尝试从线程修改 BindingList,这引发了异常,我用 google 搜索并找到了以下解释:

此问题与 XtraGrid 没有直接关系。不幸的是,您无法在后台线程中更改网格的数据源,因为这会导致很多同步问题。当您的后台线程更改它时,XtraGrid 可能会同时对底层数据源执行一些操作。在这种情况下,网格稍后可能会收到更改通知,并尝试更新数据源中的行,这将导致上述问题。这个问题在很多情况下都可能出现。例如,当用户编辑数据、对其进行分组或 XtraGrid 尝试重新计算摘要时。此问题的唯一解决方案是在后台线程中更改 Grid 的 DataSource 引用(注意:您需要使用 Invoke 方法来实现它)。换句话说,在后台线程中,您应该使用数据源的本地副本,并在必要时将其克隆传递给网格的数据源。在随附的示例中,您将找到一个演示此方法的示例项目。

我尝试了它所说的,结果是这样的:

proxyWorker = new Thread(() =>
{
    //Clone the datasource into the thread
    BindingList<Proxy> newList = new BindingList<Proxy>(proxies);

    //Set the proxy source to the cloned datasource in the thread
    gcProxies.BeginInvoke(new MethodInvoker(delegate { gcProxies.DataSource = newList; }));

   //Logic here
});

proxyWorker.Name = "proxyTester";

proxyWorker.Start();

它有效,但我不明白线程结束后数据源会发生什么? newList 不是被销毁了吗?

我的想法是,最后我会重新克隆 newList 并将其设置回 proxies (原始数据源)

最佳答案

我认为您的困惑源于这样一个事实:您认为 .NET 对象与创建它的线程相关联。事实并非如此,进程中的所有线程共享同一个GC堆。在一个线程中创建的 List<> 对象与另一个线程中创建的 List<> 对象没有什么不同,它不会以任何方式使创建它的线程保持事件状态。

线程的一个问题是,有很多类不是线程安全的。对于任何 UI 组件来说都是如此。您不能做的是从另一个线程分配此类对象的属性,而该属性值也可能在 UI 线程中使用。几乎 UI 组件的所有属性都有该限制。数据绑定(bind)特别麻烦,因为属性分配不直接可见。您仅设置数据源,而不是绑定(bind)设置的所有其他属性。使用Control.BeginInvoke或Dispatcher.BeginInvoke可以确保在创建控件的同一线程中设置属性值,从而解决线程安全问题。

关于c# - 需要对线程中创建的对象的生命周期进行解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10154033/

相关文章:

c# - C#中如何在两个字符串中查找相似的单词

winforms - F# : what is the deal with the flicker? 中的双缓冲

c# - 无法将必备组件放在与我的应用程序相同的位置

multithreading - Thread.sleep(1000) 何时 sleep 少于 1000 毫秒?

java - 使用 ExecutorService 有什么好处?

C#,打开 excel 文件并应用过滤器来检索特定行?

c# - LINQPad的IL代码是优化版吗?

c# - 与 oops 概念相关

c# - 在 WinForms 中居中和滚动的 PictureBox

java - Thread setDaemon(true) 挂起 Tomcat Shutdown