void QueueAction(T next) { var ct = CancelTokenSrc.Token; Task task = new Task(() => { // If we are cancelled before we start, push the job back on the queue so it can be dealt with by another runner. if (ct.IsCancellationRequested) { Queue.Enqueue(next); return; } SafeAction(next); }, ct); task.ContinueWith((t) => { byte val; RunningTasks.TryRemove(t, out val); WaitForTaskEvent.Set( ); }, ct); RunningTasks.TryAdd(task, 0); task.Start( ); }
/// <summary> /// Return a linked CancelToken? /// </summary> /// <param name="token"></param> public void StopEventLoop(CancellationToken token = default) { isLooping = false; var clearOnDone = AwaitAllTasks().ContinueWith(_ => RunningTasks.Clear()); RunningTasks.GetOrAdd(clearOnDone.Id, clearOnDone); }
public async Task <HttpResponseMessage> GetNewsAsync() { using (var cts = new CancellationTokenSource()) { RunningTasks.Add(RemoteRequestAsync(redditApi.GetApi(Priority.UserInitiated).GetNews(cts.Token)).Id, cts); return(await RemoteRequestAsync(redditApi.GetApi(Priority.UserInitiated).GetNews(cts.Token))); } }
public async Task <HttpResponseMessage> GetMakeUpsAsync(string brand) { using (var cts = new CancellationTokenSource()) { Task <HttpResponseMessage> task = RemoteRequestAsync(makeUpApi.GetApi(Priority.UserInitiated).GetMakeUps(brand)); RunningTasks.Add(task.Id, cts); return(await task); } }
public async Task <int> AddMakeupLocalDataAsync(List <MakeUpModel> makeUpModelList) { using var cts = new CancellationTokenSource(); Task <int> task = makeUpApi.InsertAll(AutoMapper.Map <List <MakeUp> >(makeUpModelList)); RunningTasks.Add(task.Id, cts); return(await task); }
Task AppendAwaitCompletion(Task theTask) { if (!theTask.IsCompleted) { var updatedTask = theTask.ContinueWith(t => RunningTasks.Remove(t.Id, out _)); return(RunningTasks.AddOrUpdate(theTask.Id, updatedTask, (_, t) => updatedTask)); } return(theTask); }
public async Task <List <MakeUpModel> > GetMakeupLocalDataAsync() { using (var cts = new CancellationTokenSource()) { Task <List <MakeUp> > task = makeUpApi.Get(); RunningTasks.Add(task.Id, cts); var makeUpModels = Task.Run(() => AutoMapper.Map <List <MakeUpModel> >(task.Result)); RunningTasks.Add(makeUpModels.Id, cts); return(await makeUpModels); } }
protected async Task RunImageLoadingTaskAsync(IImageLoaderTask pendingTask) { string keyRaw = pendingTask.KeyRaw; try { if (_imageLoader.VerbosePerformanceLogging) { IPlatformPerformance performance = _imageLoader.Performance; LogSchedulerStats(performance); var stopwatch = Stopwatch.StartNew(); await pendingTask.RunAsync().ConfigureAwait(false); stopwatch.Stop(); _imageLoader.Logger?.Debug(string.Format("[PERFORMANCE] RunAsync - NetManagedThreadId: {0}, NativeThreadId: {1}, Execution: {2} ms, Key: {3}", performance.GetCurrentManagedThreadId(), performance.GetCurrentSystemThreadId(), stopwatch.Elapsed.Milliseconds, pendingTask.Key)); } else { await pendingTask.RunAsync().ConfigureAwait(false); } } finally { lock (_lock) { RunningTasks.Remove(keyRaw); if (SimilarTasks.Count > 0) { SimilarTasks.RemoveAll(v => v == null || v.IsCompleted || v.IsCancelled); var similarItems = SimilarTasks.Where(v => v.KeyRaw == keyRaw); foreach (var similar in similarItems) { SimilarTasks.Remove(similar); LoadImage(similar); } } } pendingTask.TryDispose(); await TakeFromPendingTasksAndRunAsync().ConfigureAwait(false); } }
private void WaitForAvailableThread() { System.DateTime dtStart = System.DateTime.Now; while (!disposing && MaximumConcurrency <= RunningTasks.Count()) { System.Threading.Thread.Sleep(10); if (System.DateTime.Now - dtStart >= TimeOut) { throw new System.TimeoutException( string.Format(IO.FileParser.Properties.Resources.ResourceManager.GetString("ThreadNotAvailable"), TimeOut.ToString("HH:mm:ss.fff"))); } } }
protected async Task TakeFromPendingTasksAndRunAsync() { Dictionary <string, PendingTask> tasksToRun = null; lock (_pendingTasksLock) { if (RunningTasks.Count >= MaxParallelTasks) { return; } int numberOfTasks = MaxParallelTasks - RunningTasks.Count; tasksToRun = new Dictionary <string, PendingTask>(); foreach (var task in PendingTasks.Where(t => !t.ImageLoadingTask.IsCancelled && !t.ImageLoadingTask.IsCompleted) .OrderByDescending(t => t.ImageLoadingTask.Parameters.Priority ?? GetDefaultPriority(t.ImageLoadingTask.Parameters.Source)) .ThenBy(t => t.Position)) { // We don't want to load, at the same time, images that have same key or same raw key at the same time // This way we prevent concurrent downloads and benefit from caches string rawKey = task.ImageLoadingTask.KeyRaw; if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey)) { continue; } tasksToRun.Add(rawKey, task); if (tasksToRun.Count == numberOfTasks) { break; } } } if (tasksToRun != null && tasksToRun.Count > 0) { if (tasksToRun.Count == 1) { await RunImageLoadingTaskAsync(tasksToRun.Values.First(), false).ConfigureAwait(false); } else { var tasks = tasksToRun.Select(p => RunImageLoadingTaskAsync(p.Value, true)); await Task.WhenAny(tasks).ConfigureAwait(false); } } }
protected async Task RunImageLoadingTaskAsync(PendingTask pendingTask) { var key = pendingTask.ImageLoadingTask.Key; lock (_pendingTasksLock) { if (RunningTasks.ContainsKey(key)) return; RunningTasks.Add(key, pendingTask); Interlocked.Increment(ref _statsTotalRunning); } try { if (Configuration.VerbosePerformanceLogging) { LogSchedulerStats(); var stopwatch = Stopwatch.StartNew(); await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false); stopwatch.Stop(); Logger.Debug( string.Format( "[PERFORMANCE] RunAsync - NetManagedThreadId: {0}, NativeThreadId: {1}, Execution: {2} ms, Key: {3}", Performance.GetCurrentManagedThreadId(), Performance.GetCurrentSystemThreadId(), stopwatch.Elapsed.Milliseconds, key)); } else { await Task.Run(pendingTask.ImageLoadingTask.RunAsync).ConfigureAwait(false); } } finally { lock (_pendingTasksLock) { RunningTasks.Remove(key); } pendingTask?.ImageLoadingTask?.Dispose(); await TakeFromPendingTasksAndRunAsync().ConfigureAwait(false); } }
/// <summary> /// Starts the <see cref="AbortableTask">Task</see> using <see cref="TaskManager.TaskFactory">TaskFactory</see> /// and adds it to the <see cref="TaskManager.Tasks">Tasks</see> collection or the /// <see cref="TaskManager.PendingTasks">PendingTasks</see> collection if no threads are available. /// </summary> /// <param name="task"></param> public void StartTask(AbortableTask task) { if (MaximumConcurrency <= RunningTasks.Count()) { PendingTasks.Add(task); } else { Tasks.Add(task); if (TaskFactory.Scheduler == null) { task.Task.Start(); } else { task.Task.Start(TaskFactory.Scheduler); } } }
public async Task RemeberWithTestAsync() { AbandonedTasks processingEvents = new(); using (RunningTasks.RememberWith(processingEvents)) { Assert.Equal(1, processingEvents.Count); } Assert.Equal(0, processingEvents.Count); using (RunningTasks.RememberWith(processingEvents)) { Assert.Equal(1, processingEvents.Count); } Assert.Equal(0, processingEvents.Count); await processingEvents.WhenAllAsync(); }
public async Task <List <MakeUpModel> > GetMakeupLocalUsingEFDataAsync() { using (var cts = new CancellationTokenSource()) { var makeUp = new MakeUp() { Brand = "xxxxx", Category = "xxxxxxx" }; MakeUp value = UnitOfWork.GenericHandler <MakeUp>().Insert(makeUp); UnitOfWork.Save(); Task <List <MakeUp> > task = makeUpApi.Get(); RunningTasks.Add(task.Id, cts); var makeUpModels = Task.Run(() => AutoMapper.Map <List <MakeUpModel> >(task.Result)); RunningTasks.Add(makeUpModels.Id, cts); return(await makeUpModels); } }
public void SubmitTask(Task task) { RunningTasks.Add(task); }
protected async Task TakeFromPendingTasksAndRunAsync() { Dictionary<string, PendingTask> tasksToRun = null; lock (_pendingTasksLock) { var preloadOrUrlTasksCount = 0; var urlTasksCount = 0; var preloadTasksCount = 0; if (RunningTasks.Count >= MaxParallelTasks) { urlTasksCount = RunningTasks.Count( v => (v.Value?.ImageLoadingTask != null) && !v.Value.ImageLoadingTask.Parameters.Preload && (v.Value.ImageLoadingTask.Parameters.Source == ImageSource.Url)); preloadTasksCount = RunningTasks.Count(v => (v.Value?.ImageLoadingTask != null) && v.Value.ImageLoadingTask.Parameters.Preload); preloadOrUrlTasksCount = preloadTasksCount + urlTasksCount; if ((preloadOrUrlTasksCount == 0) || (preloadOrUrlTasksCount != MaxParallelTasks)) return; // Allow only half of MaxParallelTasks as additional allowed tasks when preloading occurs to prevent starvation if (RunningTasks.Count - Math.Max(1, Math.Min(preloadOrUrlTasksCount, MaxParallelTasks/2)) >= MaxParallelTasks) return; } var numberOfTasks = MaxParallelTasks - RunningTasks.Count + Math.Min(preloadOrUrlTasksCount, MaxParallelTasks/2); tasksToRun = new Dictionary<string, PendingTask>(); foreach ( var task in PendingTasks.Where(t => !t.ImageLoadingTask.IsCancelled && !t.ImageLoadingTask.IsCompleted) .OrderByDescending( t => t.ImageLoadingTask.Parameters.Priority ?? GetDefaultPriority(t.ImageLoadingTask.Parameters.Source)) .ThenBy(t => t.Position)) { // We don't want to load, at the same time, images that have same key or same raw key at the same time // This way we prevent concurrent downloads and benefit from caches var rawKey = task.ImageLoadingTask.KeyRaw; if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey)) continue; if (preloadOrUrlTasksCount != 0) { if (!task.ImageLoadingTask.Parameters.Preload && ((urlTasksCount == 0) || (task.ImageLoadingTask.Parameters.Source != ImageSource.Url))) tasksToRun.Add(rawKey, task); } else { tasksToRun.Add(rawKey, task); } if (tasksToRun.Count == numberOfTasks) break; } } if ((tasksToRun != null) && (tasksToRun.Count > 0)) if (tasksToRun.Count == 1) { await RunImageLoadingTaskAsync(tasksToRun.Values.First()).ConfigureAwait(false); } else { var tasks = tasksToRun.Select(p => RunImageLoadingTaskAsync(p.Value)); await Task.WhenAll(tasks).ConfigureAwait(false); } }
/// <summary> /// Asynchronously runs <paramref name="delegateFunction"/> for every item in the given collection /// </summary> /// <typeparam name="T">Type of the collection item</typeparam> /// <param name="delegateFunction">The function to asynchronously run</param> /// <param name="collection">The collection to be enumerated</param> /// <exception cref="InvalidOperationException">Thrown if execution starts before the end of another operation</exception> public async Task RunForEach <T>(IEnumerable <T> collection, ForEachItemAsync <T> delegateFunction) { if (RunningTasks.Count > 0) { throw new InvalidOperationException(Properties.Resources.AsyncFor_ErrorNoConcurrentExecution); } var exceptions = new List <Exception>(); var taskItemQueue = new Queue <T>(); foreach (var item in collection) { taskItemQueue.Enqueue(item); } TotalTasks = taskItemQueue.Count; // While there's either more tasks to start or while there's still tasks running while (taskItemQueue.Count > 0 || (taskItemQueue.Count == 0 && RunningTasks.Count > 0)) { if ((BatchSize < 1 || RunningTasks.Count < BatchSize) && taskItemQueue.Count > 0) { // We can run more tasks // Get the next task item to run var item = taskItemQueue.Dequeue(); // The item in Collection to process // Start the task var tTask = Task.Run(async() => { await delegateFunction(item).ConfigureAwait(false); IncrementCompletedTasks(); }); // Either wait for it or move on if (RunSynchronously) { await tTask.ConfigureAwait(false); } else { RunningTasks.Add(tTask); } } else { if (RunningTasks.Count > 0) { // We can't start any more tasks, so we have to wait on one. await Task.WhenAny(RunningTasks).ConfigureAwait(false); // Remove completed tasks for (var count = RunningTasks.Count - 1; count >= 0; count--) { if (RunningTasks[count].Exception != null) { var ex = RunningTasks[count].Exception; if (ex is AggregateException aggregateEx && aggregateEx.InnerExceptions.Count == 1) { exceptions.Add(aggregateEx.InnerExceptions.First()); } else { exceptions.Add(RunningTasks[count].Exception); } RunningTasks.RemoveAt(count); } else if (RunningTasks[count].IsCompleted) { RunningTasks.RemoveAt(count); } } }
public override async Task ExecuteAsync(object parameter) { _shell.StatusText = $"Open Async task {Thread.CurrentThread.ManagedThreadId } of {RunningTasks.Count()} "; await Task.Delay(2000); _shell.StatusText = $"Completed Open Async task {Thread.CurrentThread.ManagedThreadId } of {RunningTasks.Count()} "; }
protected async Task TakeFromPendingTasksAndRunAsync() { if (PendingTasks.Count == 0) { return; } Dictionary <string, IImageLoaderTask>?tasksToRun = null; int urlTasksCount = 0; lock (_lock) { if (RunningTasks.Count >= MaxParallelTasks) { urlTasksCount = RunningTasks.Count(v => v.Value != null && v.Value.ImageSource.Source is UriSource); if (urlTasksCount == 0 || urlTasksCount != MaxParallelTasks) { return; } // Allow only half of MaxParallelTasks as additional allowed tasks when preloading occurs to prevent starvation if (RunningTasks.Count - Math.Max(1, Math.Min(urlTasksCount, MaxParallelTasks / 2)) >= MaxParallelTasks) { return; } } int numberOfTasks = MaxParallelTasks - RunningTasks.Count + Math.Min(urlTasksCount, MaxParallelTasks / 2); tasksToRun = new Dictionary <string, IImageLoaderTask>(); while (tasksToRun.Count < numberOfTasks && PendingTasks.TryDequeue(out IImageLoaderTask? task)) { if (task == null || task.IsCancelled || task.IsCompleted) { continue; } // We don't want to load, at the same time, images that have same key or same raw key at the same time // This way we prevent concurrent downloads and benefit from caches string rawKey = task.KeyRaw; if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey)) { SimilarTasks.Add(task); continue; } if (urlTasksCount != 0) { if (!(task.ImageSource.Source is UriSource)) { tasksToRun.Add(rawKey, task); } else { Enqueue(task); break; } } else { tasksToRun.Add(rawKey, task); } } foreach (var item in tasksToRun) { RunningTasks.Add(item.Key, item.Value); Interlocked.Increment(ref _statsTotalRunning); } } if (tasksToRun != null && tasksToRun.Count > 0) { var tasks = tasksToRun.Select(async p => { await Task.Factory.StartNew(async() => { try { await RunImageLoadingTaskAsync(p.Value).ConfigureAwait(false); } catch (Exception ex) { _imageLoader.Logger?.Error("TakeFromPendingTasksAndRun exception", ex); } }, CancellationToken.None, TaskCreationOptions.PreferFairness | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler, TaskScheduler.Default).ConfigureAwait(false); }); await Task.WhenAll(tasks).ConfigureAwait(false); } }
protected async Task TakeFromPendingTasksAndRunAsync() { if (PendingTasks.Count == 0) { return; } Dictionary <string, IImageLoaderTask> tasksToRun = null; int preloadOrUrlTasksCount = 0; int urlTasksCount = 0; int preloadTasksCount = 0; lock (_lock) { if (RunningTasks.Count >= MaxParallelTasks) { urlTasksCount = RunningTasks.Count(v => v.Value != null && (!v.Value.Parameters.Preload && v.Value.Parameters.Source == ImageSource.Url)); preloadTasksCount = RunningTasks.Count(v => v.Value != null && v.Value.Parameters.Preload); preloadOrUrlTasksCount = preloadTasksCount + urlTasksCount; if (preloadOrUrlTasksCount == 0 || preloadOrUrlTasksCount != MaxParallelTasks) { return; } // Allow only half of MaxParallelTasks as additional allowed tasks when preloading occurs to prevent starvation if (RunningTasks.Count - Math.Max(1, Math.Min(preloadOrUrlTasksCount, MaxParallelTasks / 2)) >= MaxParallelTasks) { return; } } int numberOfTasks = MaxParallelTasks - RunningTasks.Count + Math.Min(preloadOrUrlTasksCount, MaxParallelTasks / 2); tasksToRun = new Dictionary <string, IImageLoaderTask>(); IImageLoaderTask task = null; while (tasksToRun.Count < numberOfTasks && PendingTasks.TryDequeue(out task)) { if (task == null || task.IsCancelled || task.IsCompleted) { continue; } // We don't want to load, at the same time, images that have same key or same raw key at the same time // This way we prevent concurrent downloads and benefit from caches string rawKey = task.KeyRaw; if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey)) { SimilarTasks.Add(task); continue; } if (preloadOrUrlTasksCount != 0) { if (!task.Parameters.Preload && (urlTasksCount == 0 || task.Parameters.Source != ImageSource.Url)) { tasksToRun.Add(rawKey, task); } else { Enqueue(task); break; } } else { tasksToRun.Add(rawKey, task); } } foreach (var item in tasksToRun) { RunningTasks.Add(item.Key, item.Value); Interlocked.Increment(ref _statsTotalRunning); } } if (tasksToRun != null && tasksToRun.Count > 0) { var tasks = tasksToRun.Select(p => RunImageLoadingTaskAsync(p.Value)); await Task.WhenAll(tasks).ConfigureAwait(false); } }
static void _Main(string[] args) { //Debug_.PrintLoadedAssemblies(true, !true); AppDomain.CurrentDomain.UnhandledException += _UnhandledException; process.ThisThreadSetComApartment_(ApartmentState.STA); process.thisProcessCultureIsInvariant = true; DebugTraceListener.Setup(usePrint: true); Directory.SetCurrentDirectory(folders.ThisApp); //it is c:\windows\system32 when restarted as admin Api.SetSearchPathMode(Api.BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE); //let SearchPath search in current directory after system directories Api.SetErrorMode(Api.GetErrorMode() | Api.SEM_FAILCRITICALERRORS); //disable some error message boxes, eg when removable media not found; MSDN recommends too. _SetThisAppDocuments(); if (CommandLine.ProgramStarted2(args)) { return; } PrintServer = new print.Server(true) { NoNewline = true }; PrintServer.Start(); #if TRACE print.qm2.use = !true; //timer.after(1, _ => perf.nw()); #endif perf.next('o'); Settings = AppSettings.Load(); //the slowest part, >50 ms. Loads many dlls. //Debug_.PrintLoadedAssemblies(true, !true); perf.next('s'); UserGuid = Settings.user; if (UserGuid == null) { Settings.user = UserGuid = Guid.NewGuid().ToString(); } AssemblyLoadContext.Default.Resolving += _Assembly_Resolving; AssemblyLoadContext.Default.ResolvingUnmanagedDll += _UnmanagedDll_Resolving; Tasks = new RunningTasks(); perf.next('t'); script.editor.IconNameToXaml_ = (s, what) => DIcons.GetIconString(s, what); FilesModel.LoadWorkspace(CommandLine.WorkspaceDirectory); perf.next('W'); CommandLine.ProgramLoaded(); perf.next('c'); Loaded = EProgramState.LoadedWorkspace; timer.every(1000, t => _TimerProc(t)); //note: timer can make Process Hacker/Explorer show CPU usage, even if we do nothing. Eg 0.02 if 250, 0.01 if 500, <0.01 if 1000. //Timer1s += () => print.it("1 s"); //Timer1sOr025s += () => print.it("0.25 s"); TrayIcon.Update_(); perf.next('i'); _app = new() { ShutdownMode = ShutdownMode.OnExplicitShutdown //will set OnMainWindowClose when creating main window. If now, would exit if a startup script shows/closes a WPF window. }; _app.Dispatcher.InvokeAsync(() => Model.RunStartupScripts()); if (!Settings.runHidden || CommandLine.StartVisible) { _app.Dispatcher.Invoke(() => ShowWindow()); } try { _app.Run(); //Hidden app should start as fast as possible, because usually starts with Windows. //Tested with native message loop. Faster by 70 ms (240 vs 310 without the .NET startup time). // But then problems. Eg cannot auto-create main window synchronously, because need to exit native loop and start WPF loop. } finally { Loaded = EProgramState.Unloading; var fm = Model; Model = null; fm.Dispose(); //stops tasks etc Loaded = EProgramState.Unloaded; PrintServer.Stop(); } }