I was trying to use Chunkify method to "catch" all "pending" items.. But I found a problem, consumes all the resources of one thread, does anyone know why this happens, and how can I prevent this?
In fact, my goal was to create a "spam filter" for my event, selecting only the last 5 values, and ignoring more than two consecutive repetitions.
An example of how the problem occurs:
Attention! The code below is stupid and pointless. It is only to demonstrate the problem, and indicate that the event can be called multiple threads (Please, run the code above and watch the output window and it is the problem).
[TestMethod]
public void ThreadSpinning()
{
var subs = Observable.FromEventPattern(add => this.Raise += add, rem => this.Raise -= rem)
.Select((item, countRaise) => countRaise)
.Chunkify()
.ToObservable(Scheduler.Default)
.Select((countRaise, countChunkify) => new { raiseItems = countRaise, countChunkify })
.Do(obj => Trace.Write("Chunkify = " + obj.countChunkify + " | "))
.Select(a => a.raiseItems)
.Where(a => a.Any())
.Do(obj =>
{
Trace.WriteLine("[ Start do something.. Raise = " + Dump(obj) + " ] " +
Environment.NewLine + Environment.NewLine);
Thread.Sleep(700);
}).Subscribe();
Thread.Sleep(2000);
var handle = new ManualResetEventSlim(false);
ThreadPool.QueueUserWorkItem(r =>
{
Thread.Sleep(500);
Task.Factory.StartNew(() =>
{
OnRaise();
OnRaise();
}).Wait();
OnRaise();
Thread.Sleep(500);
OnRaise();
Task.Factory.StartNew(OnRaise).Wait();
Thread.Sleep(1500);
OnRaise();
OnRaise();
Thread.Sleep(500);
OnRaise();
Thread.Sleep(250);
OnRaise();
Task.Factory.StartNew(OnRaise).Wait();
Thread.Sleep(500);
Task.Factory.StartNew(OnRaise).Wait();
Task.Factory.StartNew(OnRaise).Wait();
Thread.Sleep(2000);
handle.Set();
});
handle.Wait();
Thread.Sleep(3000);
subs.Dispose();
Thread.Sleep(1000);
}
private event EventHandler Raise;
protected virtual void OnRaise()
{
EventHandler handler = Raise;
if (handler != null)
handler(this, EventArgs.Empty);
}
public static string Dump<T>(IEnumerable<T> source)
{
return source.Select(a => a.ToString()).Aggregate((a, b) => a + ", " + b);
}