/// <summary> /// The is cancelled. /// </summary> /// <param name="e"> /// The e. /// </param> /// <returns> /// </returns> private static bool IsCancelled(NotifyScannerStateChangedEventArgs e) { lock (SyncRoot) { return(currentScan != e.Id); } }
/// <summary> /// The fire scanner state changed. /// </summary> /// <param name="dispatcher"> /// The dispatcher. /// </param> /// <param name="e"> /// The e. /// </param> private static void FireScannerStateChanged(Dispatcher dispatcher, NotifyScannerStateChangedEventArgs e) { NotifyScannerStateChangedEventHandler scannerStateChanged; lock (SyncRoot) { if (currentScan != e.Id) { return; } scannerStateChanged = ScannerStateChanged; } if (scannerStateChanged != null) { if (dispatcher.CheckAccess()) { scannerStateChanged(null, e); } else { dispatcher.Invoke(new Action <Dispatcher, NotifyScannerStateChangedEventArgs>(FireScannerStateChanged), DispatcherPriority.Send, dispatcher, e); } } }
/// <summary> /// The begin scan. /// </summary> /// <param name="client"> /// The client. /// </param> /// <param name="namespaceName"> /// The namespace name. /// </param> /// <param name="tableName"> /// The table name. /// </param> /// <param name="action"> /// The action. /// </param> public static void BeginScan(IClient client, string namespaceName, string tableName, Action <IList <Cell> > action) { lock (SyncRoot) { tasks = tasks.Where(t => !t.IsCompleted).ToList(); } var dispatcher = Dispatcher.CurrentDispatcher; var beginScan = Task.Factory.StartNew( () => { using (var ns = client.OpenNamespace(namespaceName)) using (var table = ns.OpenTable(tableName)) { var notify = new NotifyScannerStateChangedEventArgs(); lock (SyncRoot) { currentScan = notify.Id; } FireScannerStateChanged(dispatcher, notify); if (client.Context.HasFeature(ContextFeature.AsyncTableScanner)) { using (var asyncResult = new AsyncResult( (asyncScannerContext, cells) => { if (!IsCancelled(notify)) { FireScannerStateChanged(dispatcher, notify.Executing(cells)); action(cells); return(AsyncCallbackResult.Continue); } return(AsyncCallbackResult.Abort); })) { table.BeginScan(asyncResult); asyncResult.Join(); } } else { using (var scanner = table.CreateScanner()) using (var bc = new BlockingCollection <List <Cell> >()) { var task = Task.Factory.StartNew( () => { try { while (!IsCancelled(notify)) { var cells = bc.Take(); FireScannerStateChanged(dispatcher, notify.Executing(cells)); action(cells); } } catch (InvalidOperationException) { } }); const int ChunkSize = 2500; var chunk = new List <Cell>(ChunkSize); Cell cell; for (var c = 1; !IsCancelled(notify) && scanner.Next(out cell); ++c) { chunk.Add(cell); if ((c % chunk.Capacity) == 0) { bc.Add(chunk); chunk = new List <Cell>(ChunkSize); } } if (!IsCancelled(notify) && chunk.Count > 0) { bc.Add(chunk); } bc.CompleteAdding(); task.Wait(); } } FireScannerStateChanged(dispatcher, notify.Completed()); } }); lock (SyncRoot) { tasks.Add(beginScan); } }
/// <summary> /// The is cancelled. /// </summary> /// <param name="e"> /// The e. /// </param> /// <returns> /// </returns> private static bool IsCancelled(NotifyScannerStateChangedEventArgs e) { lock (SyncRoot) { return currentScan != e.Id; } }
/// <summary> /// The fire scanner state changed. /// </summary> /// <param name="dispatcher"> /// The dispatcher. /// </param> /// <param name="e"> /// The e. /// </param> private static void FireScannerStateChanged(Dispatcher dispatcher, NotifyScannerStateChangedEventArgs e) { NotifyScannerStateChangedEventHandler scannerStateChanged; lock (SyncRoot) { if (currentScan != e.Id) { return; } scannerStateChanged = ScannerStateChanged; } if (scannerStateChanged != null) { if (dispatcher.CheckAccess()) { scannerStateChanged(null, e); } else { dispatcher.Invoke(new Action<Dispatcher, NotifyScannerStateChangedEventArgs>(FireScannerStateChanged), DispatcherPriority.Send, dispatcher, e); } } }
/// <summary> /// The begin scan. /// </summary> /// <param name="client"> /// The client. /// </param> /// <param name="namespaceName"> /// The namespace name. /// </param> /// <param name="tableName"> /// The table name. /// </param> /// <param name="action"> /// The action. /// </param> public static void BeginScan(IClient client, string namespaceName, string tableName, Action<IList<Cell>> action) { lock (SyncRoot) { tasks = tasks.Where(t => !t.IsCompleted).ToList(); } var dispatcher = Dispatcher.CurrentDispatcher; var beginScan = Task.Factory.StartNew( () => { using (var ns = client.OpenNamespace(namespaceName)) using (var table = ns.OpenTable(tableName)) { var notify = new NotifyScannerStateChangedEventArgs(); lock (SyncRoot) { currentScan = notify.Id; } FireScannerStateChanged(dispatcher, notify); if (client.Context.HasFeature(ContextFeature.AsyncTableScanner)) { using (var asyncResult = new AsyncResult( (asyncScannerContext, cells) => { if (!IsCancelled(notify)) { FireScannerStateChanged(dispatcher, notify.Executing(cells)); action(cells); return AsyncCallbackResult.Continue; } return AsyncCallbackResult.Abort; })) { table.BeginScan(asyncResult); asyncResult.Join(); } } else { using (var scanner = table.CreateScanner()) using (var bc = new BlockingCollection<List<Cell>>()) { var task = Task.Factory.StartNew( () => { try { while (!IsCancelled(notify)) { var cells = bc.Take(); FireScannerStateChanged(dispatcher, notify.Executing(cells)); action(cells); } } catch (InvalidOperationException) { } }); const int ChunkSize = 2500; var chunk = new List<Cell>(ChunkSize); Cell cell; for (var c = 1; !IsCancelled(notify) && scanner.Next(out cell); ++c) { chunk.Add(cell); if ((c % chunk.Capacity) == 0) { bc.Add(chunk); chunk = new List<Cell>(ChunkSize); } } if (!IsCancelled(notify) && chunk.Count > 0) { bc.Add(chunk); } bc.CompleteAdding(); task.Wait(); } } FireScannerStateChanged(dispatcher, notify.Completed()); } }); lock (SyncRoot) { tasks.Add(beginScan); } }