You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET 6中如何让SynchronizedCollection具备可观察性以更新文本控件?

实现建议

方案1:包装SynchronizedCollection,添加自定义通知事件

既然SynchronizedCollection本身线程安全,我们可以通过继承它扩展通知能力,在集合修改操作完成后触发自定义事件,以此感知新项添加:

  • 自定义子类继承SynchronizedCollection<SomeClass>,重写Add、Insert等核心修改方法
  • 在方法执行完成后,触发自定义的ItemAdded事件(也可实现更通用的CollectionChanged事件)
  • 订阅事件后,在处理逻辑中切换到UI线程更新文本控件(比如WPF用Dispatcher.Invoke,WinForms用Control.Invoke)

示例代码片段:

public class NotifiableSynchronizedCollection<T> : SynchronizedCollection<T>
{
    public event EventHandler<T> ItemAdded;

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        ItemAdded?.Invoke(this, item);
    }

    protected override void AddItem(T item)
    {
        base.AddItem(item);
        ItemAdded?.Invoke(this, item);
    }
}

// 使用示例
var collection = new NotifiableSynchronizedCollection<SomeClass>();
collection.ItemAdded += (sender, newItem) =>
{
    Dispatcher.Invoke(() => txtLatestItem.Text = newItem.ToString());
};

方案2:替换为线程安全的ObservableCollection

ObservableCollection自带CollectionChanged事件,但本身非线程安全,可改造出兼顾线程安全与可观察性的版本:

  • 自定义ThreadSafeObservableCollection继承ObservableCollection<SomeClass>
  • 重写所有修改方法(Add/Insert/Remove等),用lock保证线程安全
  • 触发CollectionChanged事件时,确保逻辑在UI线程执行(通过Dispatcher或SynchronizationContext)

示例代码片段:

public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
    private readonly object _lock = new object();

    public new void Add(T item)
    {
        lock (_lock)
        {
            base.Add(item);
        }
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        Dispatcher.CurrentDispatcher.Invoke(() => base.OnCollectionChanged(e));
    }
}

// 使用示例
var collection = new ThreadSafeObservableCollection<SomeClass>();
collection.CollectionChanged += (sender, e) =>
{
    if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems.Count > 0)
    {
        var newItem = (SomeClass)e.NewItems[0];
        txtLatestItem.Text = newItem.ToString();
    }
};

方案3:定时轮询监控集合变化

如果不想修改现有集合结构,可采用轮询方式定期检查最新项:

  • 用DispatcherTimer(WPF)或System.Timers.Timer设置定时任务
  • 每次触发时,借助SynchronizedCollection的SyncRoot加锁读取,对比当前最后一项与之前记录的项,若不同则更新文本控件

示例代码片段:

var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
SomeClass lastItem = null;

timer.Tick += (sender, e) =>
{
    lock (collection.SyncRoot)
    {
        if (collection.Count > 0 && collection.Last() != lastItem)
        {
            lastItem = collection.Last();
            txtLatestItem.Text = lastItem.ToString();
        }
    }
};
timer.Start();

内容的提问来源于stack exchange,提问作者krs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 10:50:24