| 326 | | /// Manages the progress for any operation. |
| 327 | | /// </summary> |
| 328 | | private class ProgressManager |
| 329 | | { |
| 330 | | /// <summary> |
| 331 | | /// Starts measuring the speed of the task. |
| 332 | | /// </summary> |
| 333 | | public void Start() |
| 334 | | { |
| 335 | | startTime = DateTime.Now; |
| 336 | | } |
| 337 | | |
| 338 | | /// <summary> |
| 339 | | /// Tracks the amount of the operation completed. |
| 340 | | /// </summary> |
| 341 | | public long Completed |
| 342 | | { |
| 343 | | get |
| 344 | | { |
| 345 | | return completed; |
| 346 | | } |
| 347 | | set |
| 348 | | { |
| 349 | | lastCompleted += value - completed; |
| 350 | | completed = value; |
| 351 | | } |
| 352 | | } |
| 353 | | |
| 354 | | /// <summary> |
| 355 | | /// The amount to reach before the operation completes. |
| 356 | | /// </summary> |
| 357 | | public long Total |
| 358 | | { |
| 359 | | get |
| 360 | | { |
| 361 | | return total; |
| 362 | | } |
| 363 | | set |
| 364 | | { |
| 365 | | total = value; |
| 366 | | } |
| 367 | | } |
| 368 | | |
| 369 | | /// <summary> |
| 370 | | /// Gets the percentage of the operation completed. |
| 371 | | /// </summary> |
| 372 | | public float Progress |
| 373 | | { |
| 374 | | get |
| 375 | | { |
| 376 | | return (float)((double)Completed / Total); |
| 377 | | } |
| 378 | | } |
| 379 | | |
| 380 | | /// <summary> |
| 381 | | /// Computes the speed of the erase, in units of completion per second, |
| 382 | | /// based on the information collected in the previous 15 seconds. |
| 383 | | /// </summary> |
| 384 | | public int Speed |
| 385 | | { |
| 386 | | get |
| 387 | | { |
| 388 | | if (DateTime.Now == startTime) |
| 389 | | return 0; |
| 390 | | |
| 391 | | if ((DateTime.Now - lastSpeedCalc).Seconds < 5 && lastSpeed != 0) |
| 392 | | return lastSpeed; |
| 393 | | |
| 394 | | //Calculate how much time has passed |
| 395 | | double timeElapsed = (DateTime.Now - lastSpeedCalc).TotalSeconds; |
| 396 | | if (timeElapsed == 0.0) |
| 397 | | return 0; |
| 398 | | |
| 399 | | //Then compute the speed of the calculation |
| 400 | | lastSpeed = (int)(lastCompleted / timeElapsed); |
| 401 | | lastSpeedCalc = DateTime.Now; |
| 402 | | lastCompleted = 0; |
| 403 | | return lastSpeed; |
| 404 | | } |
| 405 | | } |
| 406 | | |
| 407 | | /// <summary> |
| 408 | | /// Calculates the estimated amount of time left based on the total |
| 409 | | /// amount of information to erase and the current speed of the erase |
| 410 | | /// </summary> |
| 411 | | public TimeSpan TimeLeft |
| 412 | | { |
| 413 | | get |
| 414 | | { |
| 415 | | if (Speed == 0) |
| 416 | | return new TimeSpan(0, 0, -1); |
| 417 | | return new TimeSpan(0, 0, (int)((Total - Completed) / Speed)); |
| 418 | | } |
| 419 | | } |
| 420 | | |
| 421 | | /// <summary> |
| 422 | | /// The starting time of the operation, used to determine average speed. |
| 423 | | /// </summary> |
| 424 | | private DateTime startTime; |
| 425 | | |
| 426 | | /// <summary> |
| 427 | | /// The last time a speed calculation was computed so that speed is not |
| 428 | | /// computed too often. |
| 429 | | /// </summary> |
| 430 | | private DateTime lastSpeedCalc; |
| 431 | | |
| 432 | | /// <summary> |
| 433 | | /// The last calculated speed of the operation. |
| 434 | | /// </summary> |
| 435 | | private int lastSpeed; |
| 436 | | |
| 437 | | /// <summary> |
| 438 | | /// The amount of the operation completed since the last speed computation. |
| 439 | | /// </summary> |
| 440 | | private long lastCompleted; |
| 441 | | |
| 442 | | /// <summary> |
| 443 | | /// The amount of the operation completed. |
| 444 | | /// </summary> |
| 445 | | private long completed; |
| 446 | | |
| 447 | | /// <summary> |
| 448 | | /// The amount to reach before the operation is completed. |
| 449 | | /// </summary> |
| 450 | | private long total; |
| 451 | | } |
| 452 | | |
| 453 | | /// <summary> |
| 454 | | /// Provides a common interface to track the progress made by the Erase functions. |
| 455 | | /// </summary> |
| 456 | | private class TaskProgressManager : ProgressManager |
| 457 | | { |
| 458 | | /// <summary> |
| 459 | | /// Constructor. |
| 460 | | /// </summary> |
| 461 | | public TaskProgressManager(Task task) |
| 462 | | { |
| 463 | | foreach (ErasureTarget target in task.Targets) |
| 464 | | Total += target.TotalData; |
| 465 | | |
| 466 | | Event = new TaskProgressEventArgs(task); |
| 467 | | Start(); |
| 468 | | } |
| 469 | | |
| 470 | | /// <summary> |
| 471 | | /// The TaskProgressEventArgs object representing the progress of the current |
| 472 | | /// task. |
| 473 | | /// </summary> |
| 474 | | public TaskProgressEventArgs Event |
| 475 | | { |
| 476 | | get |
| 477 | | { |
| 478 | | return evt; |
| 479 | | } |
| 480 | | set |
| 481 | | { |
| 482 | | evt = value; |
| 483 | | } |
| 484 | | } |
| 485 | | |
| 486 | | private TaskProgressEventArgs evt; |
| 487 | | } |
| 488 | | |
| 489 | | /// <summary> |
| 538 | | progress.Event.CurrentTargetStatus = S._("Searching for files' cluster tips..."); |
| 539 | | progress.Event.CurrentTargetTotalPasses = method.Passes; |
| 540 | | progress.Event.CurrentItemProgress = -1.0f; |
| 541 | | progress.Event.TimeLeft = new TimeSpan(0, 0, -1); |
| 542 | | |
| 543 | | //Start counting statistics |
| | 375 | //Define the callback handlers |
| | 376 | ProgressManager tipSearch = new ProgressManager(); |
| | 377 | progress.Steps.Add(new SteppedProgressManager.Step(tipSearch, |
| | 378 | 0.0f, S._("Searching for files' cluster tips..."))); |
| | 379 | tipSearch.Total = 1; |
| | 380 | ClusterTipsSearchProgress searchProgress = delegate(string path) |
| | 381 | { |
| | 382 | if (currentTask.Canceled) |
| | 383 | throw new OperationCanceledException(S._("The task was cancelled.")); |
| | 384 | |
| | 385 | task.OnProgressChanged(target, |
| | 386 | new ProgressChangedEventArgs(tipSearch, |
| | 387 | new TaskProgressChangedEventArgs(path, 0, 0))); |
| | 388 | }; |
| | 389 | |
| 545 | | tipProgress.Start(); |
| 546 | | |
| 547 | | //Define the callback handlers |
| 548 | | ClusterTipsSearchProgress searchProgress = delegate(string path) |
| 549 | | { |
| 550 | | progress.Event.CurrentItemName = path; |
| 551 | | task.OnProgressChanged(progress.Event); |
| | 391 | progress.Steps.Add(new SteppedProgressManager.Step(tipProgress, 0.1f, |
| | 392 | S._("Erasing cluster tips..."))); |
| | 393 | ClusterTipsEraseProgress eraseProgress = |
| | 394 | delegate(int currentFile, int totalFiles, string currentFilePath) |
| | 395 | { |
| | 396 | tipSearch.Completed = tipSearch.Total; |
| | 397 | tipProgress.Total = totalFiles; |
| | 398 | tipProgress.Completed = currentFile; |
| | 399 | task.OnProgressChanged(target, |
| | 400 | new ProgressChangedEventArgs(tipProgress, |
| | 401 | new TaskProgressChangedEventArgs(currentFilePath, 0, 0))); |
| 557 | | ClusterTipsEraseProgress eraseProgress = |
| 558 | | delegate(int currentFile, int totalFiles, string currentFilePath) |
| 559 | | { |
| 560 | | tipProgress.Total = totalFiles; |
| 561 | | tipProgress.Completed = currentFile; |
| 562 | | |
| 563 | | progress.Event.CurrentTargetStatus = S._("Erasing cluster tips..."); |
| 564 | | progress.Event.CurrentItemName = currentFilePath; |
| 565 | | progress.Event.CurrentItemProgress = tipProgress.Progress; |
| 566 | | progress.Event.CurrentTargetProgress = progress.Event.CurrentItemProgress / 10; |
| 567 | | progress.Event.TimeLeft = tipProgress.TimeLeft; |
| 568 | | task.OnProgressChanged(progress.Event); |
| 569 | | |
| 570 | | if (currentTask.Canceled) |
| 571 | | throw new OperationCanceledException(S._("The task was cancelled.")); |
| 572 | | }; |
| 573 | | |
| | 407 | //Start counting statistics |
| 626 | | progress.Completed = Math.Min(progress.Total, |
| 627 | | progress.Completed + lastWritten); |
| 628 | | progress.Event.CurrentItemPass = currentPass; |
| 629 | | progress.Event.CurrentItemProgress = progress.Progress; |
| 630 | | if (target.EraseClusterTips) |
| 631 | | progress.Event.CurrentTargetProgress = (float) |
| 632 | | (0.1f + progress.Event.CurrentItemProgress * 0.8f); |
| 633 | | else |
| 634 | | progress.Event.CurrentTargetProgress = (float) |
| 635 | | (progress.Event.CurrentItemProgress * 0.9f); |
| 636 | | progress.Event.TimeLeft = progress.TimeLeft; |
| 637 | | task.OnProgressChanged(progress.Event); |
| | 462 | mainProgress.Completed += lastWritten; |
| | 463 | task.OnProgressChanged(target, |
| | 464 | new ProgressChangedEventArgs(mainProgress, |
| | 465 | new TaskProgressChangedEventArgs(target.Drive, currentPass, method.Passes))); |
| 654 | | residentFilesProgress.Completed = currentFile; |
| 655 | | residentFilesProgress.Total = totalFiles; |
| 656 | | progress.Event.CurrentItemProgress = residentFilesProgress.Progress; |
| 657 | | progress.Event.TimeLeft = residentFilesProgress.TimeLeft; |
| 658 | | task.OnProgressChanged(progress.Event); |
| | 484 | residentProgress.Completed = currentFile; |
| | 485 | residentProgress.Total = totalFiles; |
| | 486 | task.OnProgressChanged(target, |
| | 487 | new ProgressChangedEventArgs(residentProgress, |
| | 488 | new TaskProgressChangedEventArgs(string.Empty, 0, 0))); |
| 668 | | progress.Event.CurrentTargetStatus = S._("Removing temporary files..."); |
| 669 | | task.OnProgressChanged(progress.Event); |
| | 500 | ProgressManager tempFiles = new ProgressManager(); |
| | 501 | progress.Steps.Add(new SteppedProgressManager.Step(tempFiles, |
| | 502 | 0.0f, S._("Removing temporary files..."))); |
| | 503 | task.OnProgressChanged(target, new ProgressChangedEventArgs(tempFiles, |
| | 504 | new TaskProgressChangedEventArgs(string.Empty, 0, 0))); |
| 688 | | progress.Event.TimeLeft = fsEntriesProgress.TimeLeft; |
| 689 | | progress.Event.CurrentItemProgress = fsEntriesProgress.Progress; |
| 690 | | progress.Event.CurrentTargetProgress = (float)( |
| 691 | | 0.9 + progress.Event.CurrentItemProgress / 10); |
| 692 | | task.OnProgressChanged(progress.Event); |
| | 524 | task.OnProgressChanged(target, |
| | 525 | new ProgressChangedEventArgs(structureProgress, |
| | 526 | new TaskProgressChangedEventArgs(string.Empty, 0, 0))); |
| 730 | | progress.Event.CurrentTargetProgress = i / (float)paths.Count; |
| 731 | | progress.Event.CurrentTarget = target; |
| 732 | | progress.Event.CurrentItemName = paths[i]; |
| 733 | | progress.Event.CurrentItemProgress = 0; |
| 734 | | progress.Event.CurrentTargetTotalPasses = method.Passes; |
| 735 | | task.OnProgressChanged(progress.Event); |
| | 562 | ProgressManager step = new ProgressManager(); |
| | 563 | progress.Steps.Add(new SteppedProgressManager.Step(step, |
| | 564 | 1.0f / paths.Count, S._("Erasing files..."))); |
| | 565 | task.OnProgressChanged(target, |
| | 566 | new ProgressChangedEventArgs(step, |
| | 567 | new TaskProgressChangedEventArgs(paths[i], 0, method.Passes))); |
| 774 | | dataTotal -= lastWritten; |
| 775 | | progress.Completed += lastWritten; |
| 776 | | progress.Event.CurrentItemPass = currentPass; |
| 777 | | progress.Event.CurrentItemProgress = (float) |
| 778 | | ((itemWritten += lastWritten) / (float)totalData); |
| 779 | | progress.Event.CurrentTargetProgress = |
| 780 | | (i + progress.Event.CurrentItemProgress) / |
| 781 | | (float)paths.Count; |
| 782 | | progress.Event.TimeLeft = progress.TimeLeft; |
| 783 | | task.OnProgressChanged(progress.Event); |
| 784 | | |
| 838 | | foreach (DirectoryInfo subDir in info.GetDirectories()) |
| 839 | | eraseEmptySubFolders(subDir); |
| 840 | | |
| 841 | | progress.Event.CurrentItemName = info.FullName; |
| 842 | | task.OnProgressChanged(progress.Event); |
| 843 | | |
| 844 | | FileSystemInfo[] files = info.GetFileSystemInfos(); |
| 845 | | if (files.Length == 0) |
| 846 | | fsManager.DeleteFolder(info); |
| | 667 | foreach (DirectoryInfo subDir in info.GetDirectories()) |
| | 668 | eraseEmptySubFolders(subDir); |
| | 669 | task.OnProgressChanged(target, |
| | 670 | new ProgressChangedEventArgs(step, |
| | 671 | new TaskProgressChangedEventArgs(info.FullName, 0, 0))); |
| | 672 | |
| | 673 | FileSystemInfo[] files = info.GetFileSystemInfos(); |
| | 674 | if (files.Length == 0) |
| | 675 | fsManager.DeleteFolder(info); |
| 873 | | progress.Event.CurrentTargetStatus = S._("Emptying recycle bin..."); |
| 874 | | task.OnProgressChanged(progress.Event); |
| | 703 | ProgressManager step = new ProgressManager(); |
| | 704 | progress.Steps.Add(new SteppedProgressManager.Step(step, |
| | 705 | 0.0f, S._("Emptying recycle bin..."))); |
| | 706 | task.OnProgressChanged(target, |
| | 707 | new ProgressChangedEventArgs(step, |
| | 708 | new TaskProgressChangedEventArgs(string.Empty, 0, 0))); |