public NetflixScraper(ConcurrentBag <IMedia> _mediaBag) { mediaBag = _mediaBag; netflixBaseUrl = ConfigurationManager.AppSettings["NetflixBaseUrl"]; scraperTask = new CancellableTask((token) => { // Initialize and navigation string cacheDirectory = ConfigurationManager.AppSettings["NetflixCacheDirectory"]; if (string.IsNullOrEmpty(cacheDirectory)) { cacheDirectory = Path.Combine(Environment.CurrentDirectory, "NetflixCache"); } netflixDriver = new Driver(defaultSleepTime, cacheDirectory, null, scraperTask); netflixDriver.NavigateSafely(netflixBaseUrl); // Login check, skip profile then explore content CheckLogin(); SkipProfileSelection(); netflixDriver.ScrollToBottom(defaultSleepTime * 3); netflixDriver.ScrollToTop(); // That trick ensure we will collect all the rows // Fetch then scrape CancellationToken cancellationToken = (CancellationToken)token; if (!cancellationToken.IsCancellationRequested) { FetchAll(cancellationToken); } if (!cancellationToken.IsCancellationRequested && fetchSet.Count > 0) { ScrapeAll(cancellationToken); } netflixDriver.DisposeOrKill(); }); scraperTask.ExceptionRaised += ScraperTask_ExceptionRaised; }
public void FaultsAfterSuccessesWaitForCancellations() { // 2 tasks fault, others succeed, faults occur after successes, waitForCancellations true // -> AggregateException with both faults inside CancellableTask[] tasks = new CancellableTask[] { GetLateFaultingCancellableTask(), GetLateFaultingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionWaitForCancellations(tasks); Assert.Throws <Exception>(() => waitTask.ConfigureAwait(false).GetAwaiter().GetResult()); Assert.Equal(2, waitTask.Exception.InnerExceptions.Count); Assert.All(waitTask.Exception.InnerExceptions, ex => Assert.Equal("Late Fault", ex.Message)); Assert.Equal(TaskStatus.Faulted, tasks[0].Task.Status); Assert.Equal(TaskStatus.Faulted, tasks[1].Task.Status); Assert.Equal(TaskStatus.RanToCompletion, tasks[2].Task.Status); Assert.Equal(TaskStatus.RanToCompletion, tasks[3].Task.Status); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
/// <summary> /// Stellt den Empfang einer Quelle sicher. /// </summary> /// <param name="source">Die gewünschte Quelle.</param> public void EnsureFeed(SourceSelection source) { // Unregister all outstanding requests ResetFeeds(); // Stop current reader if active - and wait for cancel to finish if (m_groupReader != null) { m_groupReader.Cancel(); m_groupReader.Wait(); } // Create new m_groupReader = ProviderDevice.Activate(source); m_feeds = _NoFeeds; // Start processing m_feedAwaiter = m_groupReader.ContinueWith(task => { // Load feed data var sources = task.Result; if (sources != null) { if (IsAllocated) { return(m_feeds = sources.Select(sourceOnGroup => new Feed(sourceOnGroup, this)).ToArray()); } } // None return(null); }); }
public void FaultsBeforeSuccessesWaitForCancellation() { // 2 tasks fault, others basically wait for cancellation and wait a bit after receiving cancellation, // fault occurs before successes, waitForCancellations true // -> AggregateException with faults inside, tasks in faulted state, other tasks are in canceled state CancellableTask[] tasks = new CancellableTask[] { GetEarlyFaultingCancellableTask(), GetEarlyFaultingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionWaitForCancellations(tasks); Assert.Throws <Exception>(() => waitTask.ConfigureAwait(false).GetAwaiter().GetResult()); Assert.Equal(2, waitTask.Exception.InnerExceptions.Count); Assert.All(waitTask.Exception.InnerExceptions, ex => Assert.Equal("Early Fault", ex.Message)); Assert.Equal(TaskStatus.Faulted, tasks[0].Task.Status); Assert.Equal(TaskStatus.Faulted, tasks[1].Task.Status); Assert.Equal(TaskStatus.Canceled, tasks[2].Task.Status); Assert.Equal(TaskStatus.Canceled, tasks[3].Task.Status); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
public void Start(BotTaskType _taskType) { if (p_tasks.ContainsKey(_taskType)) { return; } CancellableTaskProc proc; switch (_taskType) { case BotTaskType.NotificationAboutEvent: proc = p_eventNotificator.StartProcLoop; break; //case BotTaskType.NotificationAboutPartyAction: // proc = p_partyActionNotificator.StartProcLoop; // break; default: throw new ArgumentOutOfRangeException(nameof(_taskType), _taskType, null); } var task = new CancellableTask(proc, TaskCreationOptions.LongRunning, $"BotTask_{_taskType}"); p_tasks[_taskType] = task; task.Start(); }
/// <summary> /// Beginnt mit dem Laden von Quellinformationen. /// </summary> /// <param name="source">Die gewünschte Quelle.</param> /// <returns>Die Hintergrundaufgabe zum Laden der Quellinformationen.</returns> CancellableTask <SourceInformation> IDevice.GetSourceInformationAsync(SourceSelection source) { Assert.IsNotNull(m_currentSourceGroup, "not allocated"); // Make it async return(CancellableTask <SourceInformation> .Run(cancel => m_currentSourceGroup.Contains( source )?new SourceInformation { Source = source.Source } : null)); }
public void SynchronouslyCanceledTasksDoNotTakeOverBookkeeping() { // Tests fix for a bug where, when a task faults and triggers cancellation of all tasks, the // continuation for some canceled tasks (such as those not started yet) runs synchronously on the // same thread. Since the canceled task's continuation runs on the same thread as the faulted task's // continuation, a lock statement is not effective for mutual exclusion. The canceled task's // continuation runs through all the bookkeeping and ultimately results in the aggregate task // ending in a canceled state instead of a faulted state. // To recreate this situation, we need a task that faults and a task associated with a cancellation token // that does not start executing until the first task has had time to fault and run its continuation, // and a third task that is in the running state when the first task runs its continuation. CancellationTokenSource secondTaskCts = new CancellationTokenSource(); Task delayStartTask = new Task(() => { secondTaskCts.Token.ThrowIfCancellationRequested(); }, secondTaskCts.Token); CancellationTokenSource thirdTaskCts = new CancellationTokenSource(); Task runningTask = Task.Run(() => { thirdTaskCts.Token.ThrowIfCancellationRequested(); Thread.Sleep(TimeSpan.FromMilliseconds(2000)); thirdTaskCts.Token.ThrowIfCancellationRequested(); }, thirdTaskCts.Token); CancellableTask[] tasks = new CancellableTask[] { GetLateFaultingCancellableTask(), new CancellableTask(delayStartTask, secondTaskCts), new CancellableTask(runningTask, thirdTaskCts), }; Task.Delay(TimeSpan.FromMilliseconds(2000)).ContinueWith(task => { delayStartTask.Start(); }); try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(tasks); Assert.Throws <Exception>(() => waitTask.ConfigureAwait(false).GetAwaiter().GetResult()); Assert.Single(waitTask.Exception.InnerExceptions); Assert.All(waitTask.Exception.InnerExceptions, ex => Assert.Equal("Late Fault", ex.Message)); Assert.Equal(TaskStatus.Faulted, tasks[0].Task.Status); Assert.Equal(TaskStatus.Canceled, tasks[1].Task.Status); TaskStatus task3Status = tasks[2].Task.Status; Assert.True(task3Status == TaskStatus.Canceled || task3Status == TaskStatus.Running, string.Format("Third task has status {0} instead of Canceled or Running.", task3Status)); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
/* Function: Multithread * * Executes the task across multiple threads. The function passed must be suitably thread safe. This * function will not return until the task is complete. * * Parameters: * * threadName - What the execution threads should be named. "Thread #" will be appended so "Builder" will lead to * names like "Builder Thread 3". This is important to specify because thread names are reported in * exceptions and crash reports. * task - The task to execute. This must be thread safe. */ static private void Multithread (string threadName, CancellableTask task) { if (workerThreadCount == 1) { // If there's only one thread, execute it on the main thread instead of spawning a new one. // Uses fewer resources and makes debugging easier. task(Engine.Delegates.NeverCancel); } else { Engine.Thread[] threads = new Engine.Thread[workerThreadCount]; for (int i = 0; i < threads.Length; i++) { Engine.Thread thread = new Engine.Thread(); thread.Name = threadName + " Thread " + (i + 1); thread.Task = task; thread.CancelDelegate = Engine.Delegates.NeverCancel; thread.Priority = System.Threading.ThreadPriority.BelowNormal; threads[i] = thread; } foreach (var thread in threads) { thread.Start(); } foreach (var thread in threads) { thread.Join(); } foreach (var thread in threads) { thread.ThrowExceptions(); } } }
/// <summary> /// 动态调用web服务 /// </summary> /// <param name="url">服务地址</param> /// <param name="@namespace">默认命名空间</param> /// <param name="methodname">方法名称</param> /// <param name="args">参数列表</param> /// <returns></returns> public static void InvokeWebService(string url, string @namespace, string methodname, object[] args, ASyncResultCallback resultcallback) { CancellableTask task = new CancellableTask(new CancellableTask.WorkCallback((object obj) => { try { return(InvokeWebService(url, @namespace, null, methodname, args)); } catch (Exception exception) { return("请求地址不存在或请求参数错误," + exception.Message); } }), new CancellableTask.CancelCallback((object obj) => { object result = null; result = "请求被取消"; resultcallback(result); })); task.BeginInvoke(new object[] { url, methodname, args }, new AsyncCallback((IAsyncResult iresult) => { object result = null; try { result = task.EndInvoke(iresult); } catch { result = "请求超时"; } resultcallback.Invoke(result); }), null, 15 * 1000); }
/// <summary> /// Beendet die Nutzung dieses Senders. /// </summary> public void RefreshSourceInformation() { if (m_reader != null) { m_reader.Cancel(); m_reader.Wait(); } m_reader = null; }
// Should not throw. // Responsible for logging its own exceptions. // Runs on its own "long running" thread (does not occupy space in the thread pool). // Is canceled via m_stopper and waited on in Stop(). private void ListenerEntryPoint(Socket socket) { Logging.Log.Debug("Listener thread entry point."); try { while (true) { Logging.Log.Debug("Ready to accept a client."); Task <Socket> acceptTask = socket.AcceptAsync(); // Throws OperationCanceledException if cancellation was requested Socket clientSocket; try { clientSocket = acceptTask.WaitAsync(m_stopper.Token).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (Exception ex) when(!(ex is OperationCanceledException)) { Logging.Log.ErrorFormat("Error accepting a client: {0}", ex, ex.Message); continue; } Logging.Log.DebugFormat("Accepted client {0}", clientSocket.RemoteEndPoint); CancellationTokenSource connectionHandlerCanceler = new CancellationTokenSource(); long handlerTaskId = GetNextConnectionServicerTaskId(); lock (m_taskListLock) { Task connectionHandlerTask = Task.Run(async() => await NewConnectionEntryPointAsync(clientSocket, handlerTaskId, connectionHandlerCanceler.Token)); // Add task and cancellation token to a dict so service stop can wait a bit for it to complete and then cancel it. // It's important that the lock on m_taskListLock starts before the task is started. // Otherwise the task could potentially complete and attempt to remove itself // from m_connectionServicerTasks before the following line adds it. // Use an incrementing long that this class keeps track of instead of the task's ID because // task IDs can behave unexpectedly when async is involved - best to just generate // our own ID and pass it to the task. See https://blog.stephencleary.com/2013/03/taskcurrentid-in-async-methods.html m_connectionServicerTasks[handlerTaskId] = new CancellableTask(connectionHandlerTask, connectionHandlerCanceler); } } } catch (OperationCanceledException) { Logging.Log.Debug("Listener thread got a cancellation."); socket.Dispose(); Logging.Log.Debug("Listener socket disposed."); } catch (Exception ex) { Logging.Log.ErrorFormat("Listener thread got an exception: {0}", ex, ex.Message); socket.Dispose(); Logging.Log.Debug("Listener socket disposed."); } }
/// <summary> /// Aktiviert den Empfang einer Quellgruppe. /// </summary> /// <param name="source">Eine Quelle der Gruppe.</param> /// <returns>Die Hintergrundaufgabe zur Aktivierung.</returns> CancellableTask <SourceSelection[]> IDevice.Activate(SourceSelection source) { // Find the source map var group = m_provider.AllAvailableSources.SingleOrDefault(g => g.Contains(source)); Assert.IsNotNull(group, "no such source"); m_currentSourceGroup = new HashSet <SourceSelection>(); // Report return(CancellableTask <SourceSelection[]> .Run(cancel => (m_currentSourceGroup = group).ToArray())); }
/// <summary> /// 动态调用web服务 /// </summary> /// <param name="url">服务地址</param> /// <param name="@namespace">默认命名空间</param> /// <param name="methodname">方法名称</param> /// <param name="args">参数列表</param> /// <returns></returns> public static string InvokeWebService(string url, string @namespace, string methodname, object[] args) { string reqVal = string.Empty; try { CancellableTask.WorkCallback workCallBack = delegate(object obj) { object val = ""; try { val = InvokeWebService(url, @namespace, null, methodname, args); } catch (Exception exception) { SimpleConsole.WriteLine(exception); val = "请求地址不存在或参数错误"; } reqVal = val.ToString(); return(val); }; CancellableTask.CancelCallback cacelCallBack = delegate(object obj) { reqVal = "请求超时,已被取消"; }; CancellableTask task = new CancellableTask(workCallBack, cacelCallBack); AsyncCallback asyncCallback = delegate(IAsyncResult obj) { try { task.EndInvoke(obj); } catch { } SimpleConsole.WriteLine("AsyncCallback"); }; var result = task.BeginInvoke(null, asyncCallback, null, 15 * 1000); try { object endResult = task.EndInvoke(result); SimpleConsole.WriteLine(endResult); } catch (Exception exception) { SimpleConsole.WriteLine(exception); } } catch (Exception exception) { reqVal = exception.Message; } return(reqVal); }
public void CancelBeforeOthersFaultAfterCancellationDontWaitForCancellation() { // 1 task canceled, others basically wait for cancellation and wait a bit after receiving cancellation, // 2 others fault after cancellation, cancel occurs before successes and faults, waitForCancellation false // -> TaskCanceledException with Task == canceled task, other tasks are not completed yet CancellableTask[] tasks = new CancellableTask[] { GetEarlyCancellingCancellableTask(), GetLateFaultingCancellableTask(), GetLateFaultingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(tasks); bool taskCanceledCaught = false; try { waitTask.ConfigureAwait(false).GetAwaiter().GetResult(); } catch (TaskCanceledException ex) { taskCanceledCaught = true; ex.CancellationToken.Should().Be(tasks[0].CancellationTokenSource.Token); } TaskStatus task1Status = tasks[1].Task.Status; TaskStatus task2Status = tasks[2].Task.Status; TaskStatus task3Status = tasks[3].Task.Status; TaskStatus task4Status = tasks[4].Task.Status; Assert.True(taskCanceledCaught, "TaskCanceledException was not thrown."); Assert.Equal(TaskStatus.Canceled, tasks[0].Task.Status); Assert.True(task1Status == TaskStatus.Running || task1Status == TaskStatus.WaitingForActivation, string.Format("Second task has status {0} instead of Running or WaitingForActivation.", task1Status)); Assert.True(task2Status == TaskStatus.Running || task2Status == TaskStatus.WaitingForActivation, string.Format("Third task has status {0} instead of Running or WaitingForActivation.", task2Status)); Assert.True(task3Status == TaskStatus.Running || task3Status == TaskStatus.WaitingForActivation, string.Format("Fourth task has status {0} instead of Running or WaitingForActivation.", task3Status)); Assert.True(task4Status == TaskStatus.Running || task4Status == TaskStatus.WaitingForActivation, string.Format("Fifth task has status {0} instead of Running or WaitingForActivation.", task4Status)); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
/// <summary> /// Beendet die Datenübertragung in den DirectShow Graphen und zusätzlich /// eine eventuell laufende Aufzeichnung. /// </summary> /// <param name="pictureOnly">Gesetzt, wenn die Aufzeichnung selbst weiter laufen soll.</param> private void StopReceivers(bool pictureOnly) { // Stop all consumers we registered Device.RemoveProgramGuideConsumer(ReceiveEPG); Device.SetConsumerState(VideoId, null); Device.SetConsumerState(AudioId, null); Device.SetConsumerState(TextId, null); // Restart videotext caching from scratch VideoText.Deactivate(true); // Partial mode if (pictureOnly) { return; } // Stop reader using (var reader = m_InfoReader) { // Forget m_InfoReader = null; // Enforce proper shutdown if (reader != null) { reader.Cancel(); } } // Reset flag m_HasPendingGroupInformation = false; // Stop portal parser if (null != ServiceParser) { // Stop it ServiceParser.Disable(); // Forget it ServiceParser = null; } // Stop recording, too using (SourceStreamsManager recording = RecordingStream) RecordingStream = null; }
public Driver(int minimalWaitBetweenAction, string browserDataPath = "", string[] extraParameters = null, CancellableTask _cancellableTask = null) : base(CreateDefaultService(), CreateOptions(browserDataPath, extraParameters)) { // Get all processes associated to this chromedriver session (includes both chrome and chromedriver) relatedProcesses = new List <KeyValuePair <int, string> >(); foreach (var proc in Process.GetProcesses()) { if (proc.ProcessName.ToLowerInvariant().Contains("chrome") && !initProcesses.Any(x => x.Key == proc.Id)) { relatedProcesses.Add(new KeyValuePair <int, string>(proc.Id, proc.ProcessName.ToLowerInvariant())); } } cancellableTask = _cancellableTask; MinimalWaitBetweenAction = minimalWaitBetweenAction; Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(minimalWaitBetweenAction); Log.Write($"ChromeDriver instantiated", LogEntry.SeverityType.Low); }
protected virtual void WaitForCancellation() { try { Logger.Debug <CancellableTaskExecutor>($"{nameof(CancellableTask)} cancelling"); CancellableTask.Wait(); Logger.Debug <CancellableTaskExecutor>($"{nameof(CancellableTask)} cancelled"); } catch (AggregateException) { Logger.Trace <CancellableTaskExecutor>($"Handling {nameof(AggregateException)} thrown from {nameof(CancellableTask)}"); } catch (Exception ex) { Logger.Error <CancellableTaskExecutor>(ex, $"Handling unexpected error: {ex.Message}"); } }
/// <summary> /// Asynchronously advances the cursor to the next item. /// </summary> /// /// <param name="cancelToken"> /// <para> /// Used to cancel the advancement of the next item if it takes too long. /// </para> /// <para> /// The <paramref name="cancelToken"/> has no effect if the cursor still /// has buffered items to draw from. Cancellation pertains to the /// wait on an outstanding network request that is taking too long. /// </para> /// <para> /// If the <paramref name="cancelToken"/> is canceled before /// <see cref="MoveNextAsync"/> is called, <see cref="TaskCanceledException"/> /// is thrown immediately before any operation begins. /// </para> /// <para> /// Additionally, cancellation is a safe operation. When /// a <see cref="TaskCanceledException"/> is thrown, the exception will /// not disrupt the ordering of cursor items. Cancellation only pertains to /// the semantic *wait* on a pending network request. Cancellation will not /// cancel an already in-progress network request for more items. /// Therefore, a <see cref="TaskCanceledException"/> /// will not disrupt the success of future precedent calls /// to <see cref="MoveNextAsync"/>. Network requests will still arrive /// in order at some later time. /// </para> /// </param> /// /// <exception cref="TaskCanceledException"> /// <para> /// Thrown when <paramref name="cancelToken"/> is canceled before /// <see cref="MoveNextAsync"/> is called. /// </para> /// <para> /// Thrown when there are no buffered items to draw from and operation /// requires waiting on a response from the server. /// </para> /// <para> /// When <see cref="TaskCanceledException"/> is thrown the exception /// will not disrupt the ordering of items. Any non-canceled precedent calls to /// <see cref="MoveNextAsync"/> from an antecedent canceled <see cref="TaskCanceledException"/> /// will advance the cursor normally and maintain ordering of items. /// </para> /// </exception> public async Task <bool> MoveNextAsync(CancellationToken cancelToken = default) { cancelToken.ThrowIfCancellationRequested(); while (items.Count == 0) { if (!this.IsOpen) { return(false); } //our buffer is empty, we need to expect the next batch of items. if (!this.pendingContinue.IsCompleted) { //the next batch isn't here yet. so, //let's await and honor the cancelToken. //create a task that is controlled by the token. using (var cancelTask = new CancellableTask(cancelToken)) { //now await on either task, pending or the cancellation of the CancellableTask. await Task.WhenAny(this.pendingContinue, cancelTask.Task).ConfigureAwait(false); //if it was the cancelTask that triggered the continuation... throw if requested. cancelToken.ThrowIfCancellationRequested(); //else, no cancellation was requested. //we can proceed by processing the results we awaited for. } //ensure the disposal of the cancelToken registration upon exiting scope } //if we get here, the next batch should be available. var newBatch = this.pendingContinue.Result; this.pendingContinue = null; MaybeSendContinue(); this.ExtendBuffer(newBatch); } //either way, we have something to advance. AdvanceCurrent(); return(true); }
public void FaultsBeforeSuccessesDontWaitForCancellation() { // 2 tasks fault, others basically wait for cancellation and wait a bit after receiving cancellation, // fault occurs before successes, waitForCancellations false // -> AggregateException with at least 1 fault inside, at least one of first two tasks in faulted state, other tasks are not completed yet CancellableTask[] tasks = new CancellableTask[] { GetEarlyFaultingCancellableTask(), GetEarlyFaultingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(tasks); Assert.Throws <Exception>(() => waitTask.ConfigureAwait(false).GetAwaiter().GetResult()); Assert.Equal(1, waitTask.Exception.InnerExceptions.Count); Assert.Equal("Early Fault", waitTask.Exception.InnerException.Message); TaskStatus task0Status = tasks[0].Task.Status; TaskStatus task1Status = tasks[1].Task.Status; TaskStatus task2Status = tasks[2].Task.Status; TaskStatus task3Status = tasks[3].Task.Status; int numFaulted = (task0Status == TaskStatus.Faulted ? 1 : 0) + (task1Status == TaskStatus.Faulted ? 1 : 0); numFaulted.Should().BeGreaterOrEqualTo(1); Assert.True(task0Status == TaskStatus.Faulted || task0Status == TaskStatus.Running || task0Status == TaskStatus.WaitingForActivation, string.Format("First task has status {0} instead of Faulted, Running, or WaitingForActivation.", task0Status)); Assert.True(task1Status == TaskStatus.Faulted || task1Status == TaskStatus.Running || task1Status == TaskStatus.WaitingForActivation, string.Format("Second task has status {0} instead of Faulted, Running, or WaitingForActivation.", task1Status)); Assert.True(task2Status == TaskStatus.Running || task2Status == TaskStatus.WaitingForActivation, string.Format("Third task has status {0} instead of Running or WaitingForActivation.", task2Status)); Assert.True(task3Status == TaskStatus.Running || task3Status == TaskStatus.WaitingForActivation, string.Format("Fourth task has status {0} instead of Running or WaitingForActivation.", task3Status)); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
public void TypeOfExceptionWhenAwaitingIsNotAggregateException() { CancellableTask[] tasks = new CancellableTask[] { GetLateFaultingCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionWaitForCancellations(tasks); Exception exceptionWhenAwaiting = GetExceptionWhenAwaiting(waitTask).ConfigureAwait(false).GetAwaiter().GetResult(); Assert.IsType <Exception>(exceptionWhenAwaiting); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
static void Main(string[] args) { Guid lastID = default(Guid); List <CancellableTask> cancellableTasks = new List <CancellableTask>(); for (int i = 0; i < 10; i++) { CancellableTask task = new CancellableTask(() => { Console.WriteLine("New task!"); Thread.Sleep(3000); }); cancellableTasks.Add(task); lastID = task.ID; } CancellableTask cancellableTask = cancellableTasks.FirstOrDefault(x => x.ID == lastID); if (cancellableTask != null) { cancellableTask.Cancel(); } }
public void CancelBeforeOthersWaitForCancellation() { // 1 task canceled, others basically wait for cancellation and wait a bit after receiving cancellation, // cancel occurs before successes, waitForCancellation true // -> TaskCanceledException with CancellationToken == canceled task's cancellation token CancellableTask[] tasks = new CancellableTask[] { GetEarlyCancellingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionWaitForCancellations(tasks); bool taskCanceledCaught = false; try { waitTask.ConfigureAwait(false).GetAwaiter().GetResult(); } catch (TaskCanceledException ex) { taskCanceledCaught = true; ex.CancellationToken.Should().Be(tasks[0].CancellationTokenSource.Token); } Assert.True(taskCanceledCaught, "TaskCanceledException was not thrown."); Assert.Equal(TaskStatus.Canceled, tasks[0].Task.Status); Assert.Equal(TaskStatus.Canceled, tasks[1].Task.Status); Assert.Equal(TaskStatus.Canceled, tasks[2].Task.Status); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
public void CancelAfterSuccessesDontWaitForCancellation() { // 1 task canceled, others succeed, cancel occurs after successes, waitForCancellations false // -> TaskCanceledException with CancellationToken == canceled task's cancellation token CancellableTask[] tasks = new CancellableTask[] { GetLateCancellingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(tasks); bool taskCanceledCaught = false; try { waitTask.ConfigureAwait(false).GetAwaiter().GetResult(); } catch (TaskCanceledException ex) { taskCanceledCaught = true; ex.CancellationToken.Should().Be(tasks[0].CancellationTokenSource.Token); } Assert.True(taskCanceledCaught, "TaskCanceledException was not thrown."); Assert.Equal(TaskStatus.Canceled, tasks[0].Task.Status); Assert.Equal(TaskStatus.RanToCompletion, tasks[1].Task.Status); Assert.Equal(TaskStatus.RanToCompletion, tasks[2].Task.Status); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
public static void Start(bool _useConsole, string directoryPath, int _intervalBetweenPurge) { // Create color pattern foreach (var color in Enum.GetValues(typeof(ConsoleColor))) { colorPattern += $"({color}" + "{)" + "|"; } colorPattern += "(})"; // Save variable and instantiate logging intervalBetweenPurge = _intervalBetweenPurge; useConsole = _useConsole; if (IOSupport.IsDirectoryWriteable(directoryPath)) { logEntries = new ConcurrentQueue <LogEntry>(); Started = true; Write($"Application {Process.GetCurrentProcess().ProcessName} started (logging enabled)"); task = new CancellableTask((token) => { while (!((CancellationToken)token).IsCancellationRequested) { PurgeQueue(directoryPath); if (applicationExiting) { Write($"Application {Process.GetCurrentProcess().ProcessName} terminated", LogEntry.SeverityType.High); PurgeQueue(directoryPath); return; } task.SleepOrExit(intervalBetweenPurge); } }); task.Start(); } else { Write($"Application {Process.GetCurrentProcess().ProcessName} started (logging disabled)"); } }
// Loads training data and prerequisites from the database in parallel and does not return until they are loaded. private static (MalTrainingData trainingData, IDictionary <int, IList <int> > prereqs) LoadInitialData(IMalTrainingDataLoaderFactory trainingDataLoaderFactory, CancellationToken serviceStopToken) { using (IMalTrainingDataLoader initialTrainingDataLoader = trainingDataLoaderFactory.GetTrainingDataLoader()) using (CancellationTokenSource trainingDataOtherFaultOrCancellation = new CancellationTokenSource()) using (CancellationTokenSource trainingDataCancel = CancellationTokenSource.CreateLinkedTokenSource(serviceStopToken, trainingDataOtherFaultOrCancellation.Token)) using (CancellationTokenSource prereqsOtherFaultOrCancellation = new CancellationTokenSource()) using (CancellationTokenSource prereqsCancel = CancellationTokenSource.CreateLinkedTokenSource(serviceStopToken, prereqsOtherFaultOrCancellation.Token)) { CancellableAsyncFunc <MalTrainingData> trainingDataAsyncFunc = new CancellableAsyncFunc <MalTrainingData>( () => LoadTrainingDataOnInitAsync(initialTrainingDataLoader, trainingDataCancel.Token), trainingDataOtherFaultOrCancellation); CancellableTask <MalTrainingData> trainingDataTask = trainingDataAsyncFunc.StartTaskEnsureExceptionsWrapped(); CancellableAsyncFunc <IDictionary <int, IList <int> > > prereqsAsyncFunc = new CancellableAsyncFunc <IDictionary <int, IList <int> > >( () => LoadPrereqsOnInit(initialTrainingDataLoader, prereqsCancel.Token), prereqsOtherFaultOrCancellation); CancellableTask <IDictionary <int, IList <int> > > prereqsTask = prereqsAsyncFunc.StartTaskEnsureExceptionsWrapped(); AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(trainingDataTask, prereqsTask).ConfigureAwait(false).GetAwaiter().GetResult(); return(trainingDataTask.Task.Result, prereqsTask.Task.Result); } }
public void AllCompleteSuccessfullyDontWaitForCancellations() { CancellableTask[] tasks = new CancellableTask[3] { GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(tasks); waitTask.ConfigureAwait(false).GetAwaiter().GetResult(); Assert.All(tasks, task => Assert.Equal(TaskStatus.RanToCompletion, task.Task.Status)); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
public static void Register(ITimedDictionary timedDictionary) { if (timedDictionary == null) { throw new ArgumentNullException(nameof(timedDictionary)); } if (!TimedDictionaries.TryAdd(timedDictionary, DateTime.UtcNow)) { return; } if (Interlocked.Increment(ref TimedDictionartiesCount) != 1) { return; } var cleanUpTask = new CancellableTask(CleanUp); if (Interlocked.CompareExchange(ref _cleanUpTask, cleanUpTask, null) == null) { cleanUpTask.Start(); } }
public void FaultsAfterSuccessesDontWaitForCancellations() { // 2 tasks fault, others succeed, faults occur after successes, waitForCancellations false // -> AggregateException with at least one fault inside CancellableTask[] tasks = new CancellableTask[] { GetLateFaultingCancellableTask(), GetLateFaultingCancellableTask(), GetSuccessfulCancellableTask(), GetSuccessfulCancellableTask() }; try { Task waitTask = AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(tasks); Assert.Throws <Exception>(() => waitTask.ConfigureAwait(false).GetAwaiter().GetResult()); Assert.Equal(1, waitTask.Exception.InnerExceptions.Count); Assert.Equal("Late Fault", waitTask.Exception.InnerException.Message); TaskStatus task0Status = tasks[0].Task.Status; TaskStatus task1Status = tasks[1].Task.Status; int numFaulted = (task0Status == TaskStatus.Faulted ? 1 : 0) + (task1Status == TaskStatus.Faulted ? 1 : 0); numFaulted.Should().BeGreaterOrEqualTo(1); Assert.True(task0Status == TaskStatus.Faulted || task0Status == TaskStatus.Running || task0Status == TaskStatus.WaitingForActivation, string.Format("First task has status {0} instead of Faulted, Running, or WaitingForActivation.", task0Status)); Assert.True(task1Status == TaskStatus.Faulted || task1Status == TaskStatus.Running || task1Status == TaskStatus.WaitingForActivation, string.Format("Second task has status {0} instead of Faulted, Running, or WaitingForActivation.", task1Status)); Assert.Equal(TaskStatus.RanToCompletion, tasks[2].Task.Status); Assert.Equal(TaskStatus.RanToCompletion, tasks[3].Task.Status); } finally { foreach (CancellableTask task in tasks) { task.CancellationTokenSource.Dispose(); } } }
/// <summary> /// Wählt eine Quellgruppe an. /// </summary> /// <param name="source">Eine der Quellen der Gruppe.</param> /// <returns>Die Liste aller Quellen der Gruppe.</returns> public CancellableTask <SourceSelection[]> Activate(SourceSelection source) { // Map to indicated device var localSource = m_profile.FindSource(source.Source).FirstOrDefault(); if (localSource == null) { throw new ArgumentException("bad source", "source"); } // Create task return (CancellableTask <SourceSelection[]> .Run(cancel => { // Check for cancel if (cancel.IsCancellationRequested) { return _NoSources; } // Start the hardware on first call - this may take some time var device = localSource.GetHardware(); // Check for cancel if (cancel.IsCancellationRequested) { return _NoSources; } // Select the group - again this may last a bit localSource.SelectGroup(device); // Check for cancel if (cancel.IsCancellationRequested) { return _NoSources; } // Validate var groupReader = device.GroupReader; if (groupReader == null) { return _NoSources; } if (!groupReader.CancellableWait(cancel)) { return _NoSources; } // Load the map var groupInformation = groupReader.Result; if (groupInformation == null) { return _NoSources; } // Use profile to map to full source information return groupInformation .Sources .Select(s => m_profile.FindSource(s).FirstOrDefault()) .Where(s => s != null) .ToArray(); })); }
/// <summary> /// Beendet die Datenübertragung in den DirectShow Graphen und zusätzlich /// eine eventuell laufende Aufzeichnung. /// </summary> /// <param name="pictureOnly">Gesetzt, wenn die Aufzeichnung selbst weiter laufen soll.</param> private void StopReceivers( bool pictureOnly ) { // Stop all consumers we registered Device.RemoveProgramGuideConsumer( ReceiveEPG ); Device.SetConsumerState( VideoId, null ); Device.SetConsumerState( AudioId, null ); Device.SetConsumerState( TextId, null ); // Restart videotext caching from scratch VideoText.Deactivate( true ); // Partial mode if (pictureOnly) return; // Stop reader using (var reader = m_InfoReader) { // Forget m_InfoReader = null; // Enforce proper shutdown if (reader != null) reader.Cancel(); } // Reset flag m_HasPendingGroupInformation = false; // Stop portal parser if (null != ServiceParser) { // Stop it ServiceParser.Disable(); // Forget it ServiceParser = null; } // Stop recording, too using (SourceStreamsManager recording = RecordingStream) RecordingStream = null; }
/// <summary> /// Prüft, ob ein Regionalsender sein Daten verändert hat. /// </summary> /// <param name="fine">Gesetzt für den Aufruf im Sekundenrythmus.</param> public override void KeepAlive( bool fine ) { // Forward to base base.KeepAlive( fine ); // No source if (CurrentSelection == null) return; // Start reader if (m_InfoReader == null) { // Make sure that service configuration is reloaded if (!m_HasPendingGroupInformation) { // Once m_HasPendingGroupInformation = true; // Request new Device.ResetInformationReaders(); } // Check for match if (m_HasPendingGroupInformation) if (null == Device.GetGroupInformation( 0 )) return; else m_HasPendingGroupInformation = false; // Read in background m_InfoReader = CurrentSelection.GetSourceInformationAsync(); } // Only coarse if (fine) return; // See if we are done if (!m_InfoReader.IsCompleted) return; // Read the information var info = m_InfoReader.Result; // Stop reader using (var reader = m_InfoReader) { // Forget m_InfoReader = null; // Enforce proper shutdown if (reader != null) reader.Cancel(); } // Update recording if (RecordingStream != null) { // Forward RecordingStream.RetestSourceInformation( info ); // Restart silently if necessary RestartStreams(); } // See if something changed bool changed = CompareSourceInformation( info ); // Use the new one CurrentSourceConfiguration = info; // Update if (!changed) return; // Refresh audio list ResetAudio(); // Process Activate( null ); // Report ShowMessage( Properties.Resources.PSIUpdate, Properties.Resources.PSIUpdateTitle, true ); }
protected virtual void Execute() { AppDomain.CurrentDomain.ProcessExit += OnProcessExit; CancellableTask = Task.Run(() => Command(CancellationTokenSource.Token), CancellationTokenSource.Token); CancellableTask.Wait(CancellationTokenSource.Token); }
void Reload (IPhoto photo) { if (last_loader_task != null) { // last_loader_task.Cancel (); // FIXME: Re-enable this! if (last_loader_task.IsCompleted) { last_loader_task.Result.Dispose (); } } var loader = Core.PhotoLoaderCache.RequestLoader (photo); last_loader_task = loader.FindBestPreview (ThumbnailWidth, ThumbnailHeight); last_loader_task.ContinueWith ((t) => { var new_surface = PixbufImageSurface.Create (last_loader_task.Result); var cache = (ParentLayout as PhotoGridViewLayout).SurfaceCache; ThreadAssist.ProxyToMain (() => { ImageSurface old_surface = null; if (cache.TryGetValue (photo, out old_surface)) { if (old_surface != null) old_surface.Dispose (); } cache[photo] = new_surface; (ParentLayout.View as PhotoGridView).InvalidateThumbnail (photo); }); }, TaskContinuationOptions.NotOnCanceled); }