самоуничтожение объекта из списка C# - PullRequest
0 голосов
/ 22 апреля 2020

Я хочу создать объект, который выполняет какую-то работу, после того, как работа выполнена, и через некоторое время она разрушает себя. Я написал что-то, но не знаю, будет ли это работать так, как я хочу, чтобы это работало. Я использую структуру MVC в своем проекте. NET Core 2.1

Я создал класс:

public class DestroableBackroundWorker : IDestroableBackroundWorker
{       
    public int Quantity { get; set; }
    public int Successful { get; set; }
    public int Waiting { get; set; }
    public int Unsuccessful { get; set; }
    public bool Done { get; set; }
    public string Output { get; set; }
    public string ID { get; set; }

    public DestroableBackroundWorker (string jsonobject, string ID)
    {
        this.ID = ID;            
        Task.Run(() => Working(jsonobject));
        Task.Delay(3600000).ContinueWith(t => destroyme());
    }

    private void Working(string jsonobject)
    {        
        try
        {
            //does work here, updates parameters of itself, to be able to see progress
            Done = true;
            Task.Delay(120000).ContinueWith(t => destroyme());                
        }
        catch
        {
            Done = true;
            Task.Delay(120000).ContinueWith(t => destroyme());
        }
    }        

    public void destroyme()
    {
        Project.Controllers.API.BackgroundUploads.Remove(this);
    }
}

У меня также есть этот список в моем контроллере API:

public static List<IDestroableBackroundWorker> BackgroundUploads = new List<IDestroableBackroundWorker>();

Я инициирую объект из конечной точки API. Вот так:

string ID = Guid.NewGuid().ToString();
BackgroundUploads.Add(new DestroableBackroundWorker(info, ID));
return Json(ID);

Если я хочу проверить прогресс, я делаю это:

foreach (IDestroableBackroundWorker Worker in BackgroundUploads)
{
   if (Worker.ID == ID) {
      var Responce = new { All = Worker.Quantity, Success = Worker.successful, Unsuccess = Worker.unsuccessful };
      return Json(Responce);
   }
}
return Json(false);

Я хочу уничтожить этот объект, Через 2 минуты после выполнения работы или создания объекта через 1 час, будет ли это работать нормально? Я проверил, работает ли он по назначению, удаляется ли он из списка BackgroundUploads. Я также заметил, что после того, как он удаляет себя из этого Списка, он все еще работает, если он еще не закончил.

Мой вопрос состоит из двух частей:

  • это нормально? ?, если работа выполнена, а затем она удаляет себя из списка, этот объект исчез? Я имею в виду, не будет ли он использовать память или пространство?
  • как удалить его, даже если он все еще выполняет какую-то работу, не удалить указатель, но сделать так, чтобы этот объект больше не занимал память, пространство, процессор, прекратил выполнять какую-либо работу и исчез.

Ответы [ 3 ]

3 голосов
/ 22 апреля 2020

Помните, какова цель сборщика мусора; это освобождает вас от необходимости беспокоиться о том, занимает ли объект память или нет . Так что не беспокойтесь об этом!

Пусть G C выполнит свою работу. Он будет управлять временем жизни объекта для вас. Когда ваша программа больше не может получить доступ к объекту, потому что когда-либо ссылка на него больше не находится в памяти, известной как живая, память объекта будет восстановлена ​​в момент выбора G C в соответствии с его политики.

Каждый процесс имеет несколько терабайт адресного пространства. Не беспокойтесь о том, что пара дюжин байтов будет освобождена как можно скорее. Эти дюжины байтов, освобожденные через несколько секунд, не будут иметь значения между успехом и неудачей.

0 голосов
/ 22 апреля 2020

многие неправильно поняли мой вопрос, так что, вероятно, я плохо его сформулировал, но я хотел знать, как удалить этот объект из списка, а также остановить любую работу, которую он выполняет, @EricLippert указал, что, если работа уже выполнена и я удаляю его из списка, мне больше не нужно ни о чем беспокоиться. И если я хочу прекратить работу, мне нужно использовать токен отмены, поэтому я отредактировал свой класс следующим образом:

public class DestroableBackroundWorker : IDestroableBackroundWorker
{       
   public int Quantity { get; set; }
   public int Successful { get; set; }
   public int Waiting { get; set; }
   public int Unsuccessful { get; set; }
   public bool Done { get; set; }
   public string Output { get; set; }
   public string ID { get; set; }

   CancellationTokenSource cts = new CancellationTokenSource();

   public DestroableBackroundWorker (string jsonobject, string ID)
   {
      this.ID = ID;            
      Task.Run(() => Working(jsonobject, cts.Token));
      Task.Delay(3600000).ContinueWith(t => destroyme());
   }

   private void Working(string jsonobject, CancellationToken cancellationToken)
   {        
      try
      {
         //place this at appropriate place/places, where can be stopped safely             
         cancellationToken.ThrowIfCancellationRequested();             

         //does work here, updates parameters of itself, to be able to see progress
         Done = true;
         Task.Delay(120000).ContinueWith(t => destroyme());                
      }
      catch
      {
         Done = true;
         Task.Delay(120000).ContinueWith(t => destroyme());
      }
   }        

   public void destroyme()
   {
      cts.Cancel();
      Project.Controllers.API.BackgroundUploads.Remove(this);

И я считаю, что это решает эту проблему. Так что теперь, когда вызывается метод destroyme(), он также завершает работу.

0 голосов
/ 22 апреля 2020

Объект не «знает», есть ли ссылки на него. Если бы объект мог внутренне решить как-то уничтожить или аннулировать себя из существования, произошли бы плохие вещи.

Представьте себе этот сценарий - у вас есть переменная x, которая ссылается на экземпляр какого-либо объекта и вызывает его методы:

x.DoSomething();
x.DoSomethingElse();

... и затем внезапно, прямо в середине этого, объект удаляет себя из памяти. Что произойдет с существующей переменной, которая ссылается на нее? Было бы так, как будто какой-то невидимый процесс загадочным образом установил x в ноль?

Объект может быть ответственным за выполнение всех видов вещей, но определение того, продолжает ли он сам существовать в памяти, не одно и то же. из них.

Иногда объект будет внутренне ссылаться на ресурсы, на которые не влияет сборка мусора. Например, сборщик мусора не закрывает поток открытых файлов. В этих случаях вы должны реализовать IDisposable, а вызов метода Dispose должен освободить эти ресурсы. (Это не автомат c. Если вы напишите класс, который реализует IDisposable, вам придется фактически написать код или вызвать метод Dispose для освобождения ресурсов.)

Но даже тогда, это объект внутреннего управления ресурсами, которые он использует. Независимо от того, что делает метод Dispose, объект не может сделать так, чтобы ссылки на себя исчезли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...