【问题标题】:Visit domain model with second thread使用第二个线程访问域模型
【发布时间】:2017-06-25 08:55:10
【问题描述】:

我的域模型是由应用程序修改的大树结构。我想在 BackgroundWorker 中实现搜索(单独的线程不阻塞 UI)。

目前树结构是用 ObservableCollection 实现的,在修改时无法枚举,所以如果用户在我搜索时修改树,我的搜索将失败。

这个问题的优雅解决方案是什么?我的要求:不要阻止用户做任何事情(操作应该是异步的),在单独的线程上搜索(以加快速度)。

【问题讨论】:

    标签: c# multithreading collections


    【解决方案1】:

    这是我能想到的一种可以实现所需的方法:

    1. 写的时候,使用lock,创建集合的副本,添加到副本中,然后将集合重新分配给副本。

    这里有一些代码,您可以测试上述方法。使用ListBoxButton 创建一个表单。在线程上搜索列表时,您可以使用按钮将项目添加到列表中。

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace WindowsForms {
       public partial class Form1 : Form {
    
          object key = new object();
          private List<string> items;
          public Form1() {
    
             InitializeComponent();
             items = new List<string>();
             for( int i = 0; i < 100000; i++ ) {
                this.items.Add( i.ToString() );
             }
             this.listBox1.DataSource = this.items;
          }
    
          private void Read() {
    
             foreach( var thisItem in this.items ) {
                if (thisItem.ToString() == "100000" ) {
                   MessageBox.Show( "Found" );
                }
                else {
                   Thread.Sleep( 100 );
                }
             }
          }
    
          private void buttonStation2_Click(object sender, EventArgs e) {
             lock( this.key ) {
                var copy = new List<string>( this.items );
                copy.Add( "1000001" );
                this.items = copy;
             }
          }
    
          private void Form1_Shown(object sender, EventArgs e) {
             Thread reader = new Thread( Read );
             reader.Start();
          }
       }
    }
    

    您可能还想使集合变量volatile 不使用缓存版本,并且您在阅读时始终获得最新版本。但是,您确实需要在使用 volatile 关键字之前知道它的作用,这就是为什么我没有在我的代码中使用它并让您决定的原因。此外,如果其他 SO 用户愿意,可以使用 cmets 中的volatile 加入并提供他们的建议。

    private volatile List<string> items;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多