C# 中主线程循环读取子线程正在更新的集合内容,如何保证读取的是最新的数据
时间: 2024-11-09 22:22:36 浏览: 4
在C#中,当主线程需要从子线程动态更新的集合中获取最新数据时,确保同步是非常关键的。可以采用以下几种方法:
1. **使用BlockingCollection**:`BlockingCollection<T>`是一个线程安全的数据结构,允许一个或多个生产者线程向集合中添加元素,而消费者线程可以从集合中消费元素。你可以将集合作为BlockingCollection传递给子线程,然后主线程通过Take或GetResult等阻塞操作获取最新数据。
```csharp
BlockingCollection<MyObject> collection = new BlockingCollection<MyObject>();
// 子线程异步添加新数据到collection
Task.Run(() => { collection.Add(new MyObject()); });
// 主线程等待并获取最新数据
MyObject latestData = collection.Take();
```
2. **信号量或事件**:主线程可以设置一个事件或者创建一个信号量,在子线程完成数据更新后引发这个事件或释放信号量。主线程监听这个事件或等待信号量释放,然后获取数据。
```csharp
object updateLock = new object();
event WaitHandle dataUpdatedEvent = new ManualResetEvent(false);
// 更新数据后,设置事件
lock (updateLock) {
dataUpdatedEvent.Set();
}
// 主线程部分
dataUpdatedEvent.WaitOne();
MyObject latestData = GetLatestFromCollection(); // 获取方法可能需要锁保护
void GetLatestFromCollection() {
lock (updateLock) {
// 从集合中获取最新数据
}
}
```
3. **观察者模式**:如果数据更新频繁且复杂,可以使用观察者模式(Observer Pattern)。主线程订阅数据变化的观察者接口,子线程负责通知所有观察者(包括主线程)。
```csharp
public interface IDataProvider
{
event EventHandler<DataUpdatedEventArgs> DataUpdated;
}
public class MyDataProvider : IDataProvider
{
public void AddNewData()
{
// 更新数据...
OnDataUpdated(new DataUpdatedEventArgs());
}
protected virtual void OnDataUpdated(DataUpdatedEventArgs e)
{
DataUpdated?.Invoke(this, e);
}
}
// 主线程部分
var provider = new MyDataProvider();
provider.DataUpdated += (_, args) => latestData = GetLatestData();
private MyObject latestData;
MyObject GetLatestData()
{
// 从集合中获取最新数据
}
```
阅读全文