Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#在达到收集容量或发生超时时触发事件_C#_Collections_Thread Safety_Observablecollection - Fatal编程技术网

c#在达到收集容量或发生超时时触发事件

c#在达到收集容量或发生超时时触发事件,c#,collections,thread-safety,observablecollection,C#,Collections,Thread Safety,Observablecollection,当达到收集容量或超时时,我需要执行一些操作 例如,如果我有一个容量为10且超时时间为10秒的列表,则必须等待引发的某个“事件”来执行某项操作 我正在考虑使用一个可观察收集,在事件中CollectionChanged()计算收集的项目数,看看是否等于允许的最大请求数 同时,我将有一个定时器来控制超时 谁能告诉我有没有更好的解决办法 提前非常感谢。您可以使用所需的功能实现自己的收藏。 大概是这样的: static void Main() { var lis

当达到收集容量或超时时,我需要执行一些操作

例如,如果我有一个容量为10且超时时间为10秒的列表,则必须等待引发的某个“事件”来执行某项操作

我正在考虑使用一个可观察收集,在事件中CollectionChanged()计算收集的项目数,看看是否等于允许的最大请求数

同时,我将有一个定时器来控制超时

谁能告诉我有没有更好的解决办法


提前非常感谢。

您可以使用所需的功能实现自己的收藏。 大概是这样的:

  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事件的信号(如果