2017-10-05 16 views
0

多くのイベントがタスクを開始するWPFアプリケーションがあります。私のやり方は次のとおりです。しかし、私はそれが今どのように見えるか多くのタスクの完了を追跡します

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

程度満足していない示し/プロパティは、スピナー、私はそれがコールバックのように思えるProgress<T>を経た

public bool IsUpdateInProgress => taskCollection.Count > 0; 

を隠します。
すべての着信タスクが完了すると、小さなスピナーが非表示になります。

答えて

0

待つ必要があるすべてのタスクを待機するには、おそらくawait Task.WhenAll(taskCollection.ToArray());を使用する必要があります。その後、スピナーを隠すコードをawaitステートメントの下に置きます。

+0

です。実行する/タスクをグループ化する方法はありますか?多分TaskScheduler? –

+0

タスクを格納するために 'BlockingCollection'を使うことができます。さらにそれらを制御する必要がある場合は、タイマーでそれらの束を得ることができます。 – VMAtm

+0

VMAtmに感謝します。最新の変更を見つけてください –

0

私はCustomTaskSchedulerを使ってみました。私は

タスクは、様々な呼び出しから作成されたようhttp://www.codeguru.com/csharp/article.php/c18931/Understanding-the-NET-Task-Parallel-Library-TaskScheduler.htm

https://www.infoworld.com/article/3063560/application-development/building-your-own-task-scheduler-in-c.htmlからそれを得た、私は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); 
       } 
      }); 
     } 
    } 
関連する問題