Thread CreateProjectionThread(string streamId, int index, CommandProcessorContext context, ManualResetEventSlim startEvt, CancellationToken token, Stat stat)
        {
            return(new Thread(() =>
            {
                var fileName = "smartapptest-" + index;

                var views = context.Client.Views;

                var projection = new DistributionProjection(views.ReadAsJsonOrGetNew <DistributionView>(fileName));

                var totalBytes = 0;
                var sw = new Stopwatch();

                startEvt.Wait(token);
                sw.Start();

                while (!token.IsCancellationRequested)
                {
                    var nextOffset = projection.NextOffsetInBytes;

                    IEnumerable <RetrievedEventsWithMetaData> records;
                    try
                    {
                        records = context.Client.EventStores.ReadAllEvents(new EventStoreOffset(nextOffset), 10000);
                    }
                    catch (Exception e)
                    {
                        Interlocked.Increment(ref _failures);
                        context.Log.ErrorException(e, "Projection {0}: event read error", index);
                        Thread.Sleep(500);
                        continue;
                    }

                    var emptyData = true;
                    foreach (var dataRecord in records)
                    {
                        totalBytes += dataRecord.EventData.Length;

                        if (dataRecord.StreamId != streamId)
                        {
                            projection.NextOffsetInBytes = dataRecord.Next.OffsetInBytes;
                            continue;
                        }

                        projection.Handle(dataRecord.EventData);
                        projection.NextOffsetInBytes = dataRecord.Next.OffsetInBytes;

                        emptyData = false;
                    }

                    if (emptyData)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }

                    try
                    {
                        views.WriteAsJson(projection.View, fileName);
                    }
                    catch (Exception e)
                    {
                        Interlocked.Increment(ref _failures);
                        context.Log.ErrorException(e, "Projection {0}: view write error", index);
                    }
                }

                sw.Stop();
                stat.Count = totalBytes;
                stat.ElapsedMsec = sw.ElapsedMilliseconds;
            }));
        }
        Thread CreateProjectionThread(string streamId, int index, CommandProcessorContext context, ManualResetEventSlim startEvt, CancellationToken token, Stat stat)
        {
            return new Thread(() =>
                {
                    var fileName = "smartapptest-" + index;

                    var views = context.Client.Views;

                    var projection = new DistributionProjection(views.ReadAsJsonOrGetNew<DistributionView>(fileName));

                    var totalBytes = 0;
                    var sw = new Stopwatch();

                    startEvt.Wait(token);
                    sw.Start();

                    while (!token.IsCancellationRequested)
                    {
                        var nextOffset = projection.NextOffsetInBytes;

                        IEnumerable<RetrievedEventsWithMetaData> records;
                        try
                        {
                            records = context.Client.EventStores.ReadAllEvents(new EventStoreOffset(nextOffset), 10000);
                        }
                        catch (Exception e)
                        {
                            Interlocked.Increment(ref _failures);
                            context.Log.ErrorException(e, "Projection {0}: event read error", index);
                            Thread.Sleep(500);
                            continue;
                        }

                        var emptyData = true;
                        foreach (var dataRecord in records)
                        {
                            totalBytes += dataRecord.EventData.Length;

                            if (dataRecord.StreamId != streamId)
                            {
                                projection.NextOffsetInBytes = dataRecord.Next.OffsetInBytes;
                                continue;
                            }

                            projection.Handle(dataRecord.EventData);
                            projection.NextOffsetInBytes = dataRecord.Next.OffsetInBytes;

                            emptyData = false;
                        }

                        if (emptyData)
                        {
                            Thread.Sleep(1000);
                            continue;
                        }

                        try
                        {
                            views.WriteAsJson(projection.View, fileName);
                        }
                        catch (Exception e)
                        {
                            Interlocked.Increment(ref _failures);
                            context.Log.ErrorException(e, "Projection {0}: view write error", index);
                        }
                    }

                    sw.Stop();
                    stat.Count = totalBytes;
                    stat.ElapsedMsec = sw.ElapsedMilliseconds;
                });
        }