c#在达到收集容量或发生超时时触发事件
当达到收集容量或超时时,我需要执行一些操作 例如,如果我有一个容量为10且超时时间为10秒的列表,则必须等待引发的某个“事件”来执行某项操作 我正在考虑使用一个可观察收集,在事件中CollectionChanged()计算收集的项目数,看看是否等于允许的最大请求数 同时,我将有一个定时器来控制超时 谁能告诉我有没有更好的解决办法c#在达到收集容量或发生超时时触发事件,c#,collections,thread-safety,observablecollection,C#,Collections,Thread Safety,Observablecollection,当达到收集容量或超时时,我需要执行一些操作 例如,如果我有一个容量为10且超时时间为10秒的列表,则必须等待引发的某个“事件”来执行某项操作 我正在考虑使用一个可观察收集,在事件中CollectionChanged()计算收集的项目数,看看是否等于允许的最大请求数 同时,我将有一个定时器来控制超时 谁能告诉我有没有更好的解决办法 提前非常感谢。您可以使用所需的功能实现自己的收藏。 大概是这样的: static void Main() { var lis
提前非常感谢。您可以使用所需的功能实现自己的收藏。 大概是这样的:
static void Main()
{
var list = new MyObservableCollection<int>(10, 10);
list.ConditionReachedEvent += () =>
{
//Do something
};
list.StartTimer();
Task.Factory.StartNew(
() =>
{
// Simulate slow operation
Thread.Sleep(12000);
for (var i = 0; i < 10; i++)
{
list.Add(i);
}
});
Console.Read();
}
public sealed class MyObservableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T>
{
public event Action ConditionReachedEvent = delegate { };
private System.Threading.Timer timer;
private readonly int alertThreshold;
private long isEventRaised = 0;
private readonly int timeout = 0;
public MyObservableCollection(int alertThreshold, int timeout)
{
this.alertThreshold = alertThreshold;
this.timeout = timeout * 1000;
}
public void StartTimer()
{
Interlocked.Exchange(ref this.isEventRaised, 0);
this.StopTimer();
this.timer = new Timer(x =>
{
this.RaiseEvent();
}, null, this.timeout, this.timeout);
}
private void StopTimer()
{
if (this.timer != null)
{
this.timer.Dispose();
this.timer = null;
}
}
protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
if (this.Count >= this.alertThreshold)
{
this.RaiseEvent();
}
}
private void RaiseEvent()
{
this.StopTimer();
if (Interlocked.CompareExchange(ref this.isEventRaised, 1, 0) != 0)
{
return;
}
this.ConditionReachedEvent();
}
}
static void Main()
{
var列表=新的MyObservableCollection(10,10);
list.ConditionReachedEvent+=()=>
{
//做点什么
};
list.StartTimer();
Task.Factory.StartNew(
() =>
{
//模拟慢速运行
睡眠(12000);
对于(变量i=0;i<10;i++)
{
列表.添加(i);
}
});
Console.Read();
}
公共密封类MyObservableCollection:System.Collections.ObjectModel.ObservableCollection
{
公共事件操作条件reachedEvent=委托{};
专用系统。线程。计时器;
私有只读int警报阈值;
私人长等腹侧=0;
私有只读int超时=0;
公共MyObservableCollection(int alertThreshold,int timeout)
{
this.alertThreshold=alertThreshold;
this.timeout=超时*1000;
}
公共无效StartTimer()
{
互锁交换(参考本文件,0);
这个.StopTimer();
this.timer=新计时器(x=>
{
this.RaiseEvent();
},null,this.timeout,this.timeout);
}
私有void StopTimer()
{
如果(this.timer!=null)
{
this.timer.Dispose();
this.timer=null;
}
}
CollectionChanged上的受保护覆盖无效(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
基础。变更的集合(e);
如果(this.Count>=this.alertThreshold)
{
this.RaiseEvent();
}
}
私有void RaiseEvent()
{
这个.StopTimer();
if(互锁比较交换(参考此isEventRaised,1,0)!=0)
{
返回;
}
this.ConditionReachedEvent();
}
}
使用异步/等待
static void Main()
{
var list = new MyObservableCollection<int>(10);
list.ConditionReachedEvent += () =>
{
};
list.Start(10);
Task.Run(
() =>
{
// Simulate slow operation
Thread.Sleep(TimeSpan.FromSeconds(12));
for (var i = 0; i < 10; i++)
{
list.Add(i);
}
});
Console.Read();
}
public sealed class MyObservableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T>
{
public event Action ConditionReachedEvent = delegate { };
private readonly int alertThreshold;
private readonly TaskCompletionSource<object> capacityReached = new TaskCompletionSource<object>();
public MyObservableCollection(int alertThreshold)
{
this.alertThreshold = alertThreshold;
}
public async void Start(int timeout)
{
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeout));
var capacityReachedTask = capacityReached.Task;
await Task.WhenAny(capacityReachedTask, timeoutTask);
this.ConditionReachedEvent();
}
protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
if (this.Count >= this.alertThreshold)
{
capacityReached.TrySetResult(null);
}
}
}
static void Main()
{
var列表=新的MyObservableCollection(10);
list.ConditionReachedEvent+=()=>
{
};
开始(10);
任务。运行(
() =>
{
//模拟慢速运行
线程睡眠(时间跨度从秒(12));
对于(变量i=0;i<10;i++)
{
列表.添加(i);
}
});
Console.Read();
}
公共密封类MyObservableCollection:System.Collections.ObjectModel.ObservableCollection
{
公共事件操作条件reachedEvent=委托{};
私有只读int警报阈值;
private readonly TaskCompletionSource capacityReached=新建TaskCompletionSource();
公共MyObservableCollection(int alertThreshold)
{
this.alertThreshold=alertThreshold;
}
公共异步无效启动(int超时)
{
var timeoutTask=Task.Delay(TimeSpan.FromSeconds(timeout));
var capacityReachedTask=capacityReached.Task;
等待任务。何时(capacityReachedTask、timeoutTask);
this.ConditionReachedEvent();
}
CollectionChanged上的受保护覆盖无效(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
基础。变更的集合(e);
如果(this.Count>=this.alertThreshold)
{
capacityReached.TrySetResult(空);
}
}
}
如果我这样做,我会使用微软的反应式框架(NuGet“Rx Main”)。然后你可以这样做:
var collection = new ObservableCollection<int>();
var query =
Observable
.FromEventPattern<
NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
h => collection.CollectionChanged += h, h => collection.CollectionChanged -= h)
.Select(ep => collection.Count == 10)
.Where(x => x)
.Take(1)
.Timeout(TimeSpan.FromSeconds(10.0), Observable.Return(false));
query.Subscribe(flag =>
{
if (flag) // capacity
{
}
else //timeout
{
}
});
var collection=newobservetecollection();
变量查询=
可观察
.FromEventPattern<
NotifyCollectionChangedEventHandler,NotifyCollectionChangedEventArgs>(
h=>collection.CollectionChanged+=h,h=>collection.CollectionChanged-=h)
.Select(ep=>collection.Count==10)
.其中(x=>x)
.采取(1)
.超时(TimeSpan.FromSeconds(10.0),可观察。返回(false));
query.Subscribe(标志=>
{
if(flag)//容量
{
}
else//超时
{
}
});
因此,查询
有效地监视CollectionChanged
事件,并计算计数是否等于10,仅在计数为10时过滤(并返回true
),并取一个值。然后它施加一个超时,在10.0秒后返回false
。我会在“watcher”线程上使用。WaitOne方法可能超时或收到CollectionChanged事件的信号(如果