2017-10-05 81 views
0

我有一个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>
当所有传入任务完成时,一个小微调将被隐藏。

回答

0

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

+0

新任务是从不同的代码路径输入。有没有办法在合乎逻辑的地方运行/分组所有任务..也许是TaskScheduler? –

+0

如果您需要更多的控制权,您可以使用BlockingCollection来存储任务,并通过定时器获取一堆。 – VMAtm

+0

感谢VMAtm。请找到最新的变化 –

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); 
    } 
} 

该代码尚未完成。这将是巨大的,如果有人能指向正确的方向

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); 
       } 
      }); 
     } 
    }