跟踪许多任务的完成情况

时间:2017-10-05 22:07:47

标签: wpf task-parallel-library

我有一个WPF应用程序,其中有很多事件启动任务。这是我如何做到这一点。但我现在看起来并不高兴

 var task = UpdatePersonModelAsync();
 taskCollection.Add(task);
 RaisePropertyChanged(nameof(IsUpdateInProgress));
 await task;
 taskCollection.Remove(task);
 RaisePropertyChanged(nameof(IsUpdateInProgress));

显示/隐藏微调器的属性

public bool IsUpdateInProgress => taskCollection.Count > 0;

我正在浏览Progress<T>这似乎是一个回电 当所有传入的任务完成后,将隐藏一个小的微调器。

3 个答案:

答案 0 :(得分:0)

您可能应该使用await Task.WhenAll(taskCollection.ToArray());等待所有需要等待的任务。之后,将用于隐藏微调器的代码放在await语句下面。

答案 1 :(得分:0)

我尝试使用CustomTaskScheduler。我是从https://www.infoworld.com/article/3063560/application-development/building-your-own-task-scheduler-in-c.html

得到的

http://www.codeguru.com/csharp/article.php/c18931/Understanding-the-NET-Task-Parallel-Library-TaskScheduler.htm

当从各种调用创建任务时,我在Task.Factory.StartNew中使用CustomTaskScheduler。

在调试时,我可以在QueueTask上点击但是Execute没有被调用。我错过了什么?

public sealed class CustomTaskScheduler : TaskScheduler, IDisposable
{
    public delegate void TaskStartedHandler(Task sender);
    public delegate void AllTasksCompletedHandler(IEnumerable<Task> sender);

    public event TaskStartedHandler TaskStarted;
    public event AllTasksCompletedHandler AllTasksCompleted;

    private BlockingCollection<Task> tasksCollection = new BlockingCollection<Task>();
    private readonly Thread mainThread = null;

    public CustomTaskScheduler()
    {
        mainThread = new Thread(new ThreadStart(Execute));
        if (!mainThread.IsAlive)

        {
            mainThread.Start();
        }

    }

    private void Execute()
    {
        foreach (var task in tasksCollection.GetConsumingEnumerable())
        {

            var isStarted = TryExecuteTask(task);
            if (isStarted && TaskStarted != null)
            {
                TaskStarted(task);
            }
        }

        if(tasksCollection.GetConsumingEnumerable().All(m => m.IsCompleted))
        {
            AllTasksCompleted?.Invoke(tasksCollection.GetConsumingEnumerable());
        }
    }

    protected override IEnumerable<Task> GetScheduledTasks()
    {
        return tasksCollection.ToArray();
    }

    protected override void QueueTask(Task task)
    {
        if (task != null)
        {
            tasksCollection.Add(task);
        }
    }

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
    {
        return false;
    }
    private void Dispose(bool disposing)
    {
        if (!disposing)
        {
            return;
        }

        tasksCollection.CompleteAdding();
        tasksCollection.Dispose();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

代码尚未完成。如果有人可以指向正确的方向,那就太棒了

答案 2 :(得分:0)

这是新版本

public class TaskTracker
    {
        public delegate void AllTasksCompletedHandler(object sender);
        public delegate void TaskStartedHandler();
        public event AllTasksCompletedHandler AllTasksCompleted;
        public event TaskStartedHandler TaskStarted;

        private object syncLock = new object();
        private SynchronizedCollection<Task> tasksCollection;
        private bool isTaskStartedNotified;
        private readonly uint delay;

        public TaskTracker(uint delayBeforeRemovingTasks)
        {
            tasksCollection = new SynchronizedCollection<Task>();
            delay = delayBeforeRemovingTasks;
        }

        public void Add(Task task)
        {

            if (!isTaskStartedNotified)
            {
                isTaskStartedNotified = true;
                TaskStarted?.Invoke();
            }

            task.ContinueWith(t =>
            {
                RemoveTask(t);
            });

            tasksCollection.Add(task);
        }


        private async void RemoveTask(Task task)
        {
            await Task.Delay(300);
            await Task.Run(() =>
             {
                 tasksCollection.Remove(task);

                 if (tasksCollection.Count == 0)
                 {
                     isTaskStartedNotified = false;
                     AllTasksCompleted?.Invoke(tasksCollection);
                 }
             });
        }
    }