【问题标题】:Create new Thread clear file and folder c#创建新的线程清除文件和文件夹c#
【发布时间】:2021-08-17 18:43:42
【问题描述】:

我创建了一个线程来自动删除“C:\Classified Defects\data”中的文件和文件夹。 首先我使用定时器来检查磁盘空间,如果超过 80% 则调用删除函数运行。 如果小于50%就会停止。这里我用progressBar来显示驱动器的大小:

 [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
        private void timerCleanup_Tick(object sender, EventArgs e)
        {
            long result, total, free, available;
            result = GetDiskFreeSpaceEx("C:", out available, out total, out free);
            if (result != 0)
            {
                long TotalGB = total / (1024 * 1024 * 1024);
                long freeFB = free / (1024 * 1024 * 1024);
                i = Convert.ToInt32(TotalGB - freeFB);
                CircleProgressBarDisk.Maximum = 100;
                Persent = Convert.ToInt32(i * 100 / TotalGB);
                lbPersion.Text = Persent.ToString() + "%";
                CircleProgressBarDisk.Value = Persent;
                if (Persent >= 80)
                {
                    Thread Cle = new Thread(Cleanup);//I created a new thread to call the Cleanup function
                    Cle.IsBackground = true;
                    string dirname = @"C:\ClassifiedDefects\data";
                    System.IO.DirectoryInfo di = new DirectoryInfo(dirname);
                     if (di.Exists)
                        {
                            CircleProgressBarDisk.Animated = true;
                            Cle.Start();
                            if (Persent <= 50)
                            {
                                Cle.Abort(1000);
                            }
                        }
                        else 
                          { lbFilename.Text = "Not found folder source!";}
                }
            }
        }
       private void Cleanup()
        {
            string dirname = @"C:\ClassifiedDefects\data";
            System.IO.DirectoryInfo di = new DirectoryInfo(dirname);
            if (di.Exists)
            {
                if (DateTime.UtcNow - di.CreationTimeUtc < TimeSpan.FromDays(7))
                    foreach (FileInfo file in di.GetFiles())
                    {
                        file.Delete();
                        lbFilename.Text = (file.Name);
                    }
            }
            if (di.Exists)
            {
                foreach (DirectoryInfo dir in di.GetDirectories())
                {
                    dir.Delete(true);
                    lbFilename.Text = (dir.Name);
                }
            }
        }

代码可以运行,但运行时会占用非常高的计算机资源。让电脑死机,请教我:最有效的删除所有文件和文件夹的最佳方法是什么!

【问题讨论】:

  • 工作需要计算机资源。如果你想使用更少的资源,你需要做更少的工作。根据上面不完整的代码示例,我猜您将计时器间隔设置得太短。您应该 a) 为计时器使用合理的长间隔,并 b) 调整实现,以便如果代码当前仍在清理,它不会开始再次尝试在清洁。如果您需要更多建议,请修正您的问题,以便包含正确的 minimal reproducible example 以可靠地重现问题。
  • 背景Thread 可能在完成之前被垃圾收集。为防止这种情况发生,请将线程对象的引用保留为类成员变量。
  • 另外,根据timerCleanup_Tick(...) 被调用的频率,if (Persent &gt;= 80) 条件可能会被多次满足,并且每次它都会启动一个新线程。所以你会有多个线程试图删除同一个目录。
  • @Loathing: “后台线程可能在完成之前被垃圾收集”——这充其量是误导。 Thread 对象只有在不可访问时才会被 GC 处理。如果您有对它的引用,那么根据定义它是可以访问的。 Thread 对象本身是否可以访问或是否仍然可以访问将对线程本身产生no影响,因此Thread 对象的状态与此问题完全无关。

标签: c# winforms file directory del


【解决方案1】:

让我们让生活变得更简单,只有在目录增长超过预定大小时才删除超过 7 天的文件(磁盘因其他原因而被填满;如果磁盘超过 80% 则触发删除可能会导致每个 Tick 触发删除即使没有什么可删除的)

private void Timer_Tick(object sender, EventArgs e){

    timer.Stop();

    try{
      var dir = new DirectoryInfo(PATH);
      dir.Create(); //ensure exists, no-op if it does 

      var files = dir.GetFiles("*.*", SearchOption.AllDirectories);

      int deleted = 0;
      if(files.Sum(f => f.Length) > MAX_DIR_SIZE){

        foreach(var file in files.Where(f=>f.CreationTime < DateTime.UtcNow.AddDays(DELETE_FILES_OVER_DAYS_AGE))
          try{ f.Delete(); deleted++; } catch(Exception e) { statusListBox.Items.Add($"{e.Message} - {f.FileName}");

        if(deleted == 0)
          statusListBox.Items.Add($"Dir size is above the {MAX_DIR_SIZE} threshold but all files within are younger than {DELETE_FILES_OVER_DAYS_AGE} days. Adjust the DELETE_FILES_OVER_DAYS_AGE setting");
      }

      var dirs = files.Select(f => f.DirectoryName.ToLower()).Distinct;
      var root = PATH.ToLower().TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

      foreach(string d in dirs.Except(new [] { root }))

        try{ Directory.Delete(d); } //remove empties 
        catch(IOException) { } //ignore IO errors like "not empty"
        catch(Exception e) { 
          statusListBox.Items.Add($"{e.Message} - {f.FileName}");
        }

    } 
    finally{
      timer.Interval = 10*60*1000; //ten mins
      timer.Start();
    }

}

只需检查不删除根文件夹(选择除根以外的不同文件目录)的逻辑是否成功跳过根文件夹。

【讨论】:

    猜你喜欢
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 2016-09-08
    相关资源
    最近更新 更多