Как распорядиться заданием как можно быстрее - PullRequest
0 голосов
/ 20 мая 2019

У меня есть приложение формы Windows, которое я хочу, чтобы на каждом OnLoad запускалась асинхронная Task, которая устанавливается на следующем OnLoad.

После запуска с Profiler я вижу, что число объектов становится больше и больше после каждого OnLoad. Я знаю, что GC не освобождает память при вызове Dispose и при установке на null. Должен ли я переопределить финализатор? Я также рассмотрел CancellationTokenSource, но я

Форма

public class MyForm:Form
{
   private Task task;
   protected override OnLoad()
   {
     if(this.task!=null)
     {
          this.task.Dispose();
          this.task=null;
     }
     this.task=Task.Run(()=>....);
   }
}

с токеном

public class MyForm:Form
    {
       private Task task;
       private CancellationTokenSource=new CancellationTokenSource();
       protected override OnLoad()
       {
         if(this.task!=null)
         {
              src.Cancel();
         }
         try
         {
         this.task=Task.Run(()=>....,src.Token);
         }catch(TaskCancelledException ex)
         {
              return;
         }

       }
    }

Проблема с CancellationTokenSource заключается в том, что, как вы можете видеть, я бы позвонил Cancel на предыдущем Task (при втором OnLoad вызове я бы выбрал первый Task), и я не знаю, если это будет обработано в блоке Try-Catch.

Какой хороший способ избавиться от объекта Task как можно скорее? Это Form будет непрерывно перезагружаться на компьютере через определенные промежутки времени, и я не хочу его утилизировать, просто Task

1 Ответ

1 голос
/ 22 мая 2019

Вам не нужно избавляться от задач в вашей ситуации. Он реализует только IDisposable, потому что может выделить WaitHandle (который является одноразовым):

Внутренне, Задача может выделить WaitHandle, который можно использовать для ожидания завершения Задачи. WaitHandle является IDisposable, потому что он удерживает SafeWaitHandle внутри, который является IDisposable. SafeWaitHandle оборачивает собственный ресурс дескриптора: если SafeWaitHandle не утилизируется, в конечном итоге его финализатор может приступить к очистке обернутого дескриптора, но в то же время его ресурсы не будут очищены, и на систему будет оказано давление. Внедрив IDisposable on Task, мы даем возможность разработчикам, обеспокоенным агрессивной очисткой этих ресурсов, сделать это своевременно.

Теперь Microsoft осознала, что это может создать путаницу, поэтому они внесли некоторые изменения и разработали руководство:

Мы значительно снизили вероятность того, что WaitHandle Задачи будет выделен вообще. Мы повторно реализовали WaitAll и WaitAny, чтобы они не полагались на WaitHandle Задачи, и мы избегали использовать его внутри для какой-либо новой задачи или функции, связанной с асинхронностью / ожиданием, представленной в .NET 4.5. Таким образом, единственный способ размещения WaitHandle - это если вы явно запросите IAsyncResult.AsyncWaitHandle Задачи, и это должно быть довольно редко. Это означает, что за исключением таких очень редких обстоятельств, избавление от Задачи совершенно не требуется.

и

Мы сделали Задачи пригодными для использования даже после их утилизации. Теперь вы можете использовать всех открытых участников Task даже после его удаления, и они будут вести себя так же, как и до удаления. Единственный член, который вы не можете использовать, - это IAsyncResult.AsyncWaitHandle, поскольку именно это фактически удаляется при удалении экземпляра Task; это свойство будет продолжать генерировать исключение ObjectDisposedException, если вы попытаетесь использовать его после удаления Задачи. Это означает, что вы должны свободно чувствовать себя комфортно, кешируя выполненные Задачи, зная, что они являются чисто наблюдательными. Кроме того, в будущем использование IAsyncResult должно значительно упасть, поскольку у нас есть async / await и шаблон асинхронной обработки на основе задач, и даже для дальнейшего использования IAsyncResult использование его AsyncWaitHandle довольно редко.

Однако основной совет:

«Нет. Не беспокойтесь об утилизации своих задач ». Зачастую трудно найти подходящее место для этого, практически нет причин делать это, и, в зависимости от ваших справочных сборок, вы даже не сможете этого сделать.

( источник )

...