public Subscription Subscribe( CancellationToken ct, long start, int bufferSize, int cacheSize ) { var sub = new Subscription(); sub.Task = Task.Factory.StartNew(() => RunSubscription(sub, start, ct, bufferSize, cacheSize), TaskCreationOptions.LongRunning); return sub; }
void RunSubscription( Subscription sub, long position, CancellationToken ct, int bufferSize, int cacheSize ) { sub.DebugStartPosition = position; var buffer = new byte[bufferSize]; // forever try while (!ct.IsCancellationRequested) { try { // read current max length var length = _position.Read(); sub.DebugKnownMaxOffset = length; using (var prs = new PageReadStream(_messages, position, length, buffer)) { using (var bin = new BinaryReader(prs)) { while (prs.Position < prs.Length) { var message = StorageFormat.Read(bin); sub.Buffer.Enqueue(message); sub.DebugEnqueuedOffset = prs.Position; position = prs.Position; while (sub.Buffer.Count >= cacheSize) { ct.WaitHandle.WaitOne(500); } } } } // wait till we get chance to advance while (_position.Read() == position) { if (ct.WaitHandle.WaitOne(1000)) { return; } } } catch (Exception ex) { Debug.Print("Exception {0}", ex); ct.WaitHandle.WaitOne(1000*5); } } }