-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathProgressManager.cs
More file actions
155 lines (129 loc) · 3.91 KB
/
Copy pathProgressManager.cs
File metadata and controls
155 lines (129 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System;
using System.Diagnostics;
using System.Management.Automation;
namespace PSParallel
{
class ProgressManager
{
public int TotalCount { get; set; }
private ProgressRecord _progressRecord;
private readonly Stopwatch _stopwatch;
private string _currentOperation;
public ProgressManager(int activityId, string activity, string statusDescription, int parentActivityId = -1, int totalCount = 0)
{
TotalCount = totalCount;
_stopwatch = new Stopwatch();
_progressRecord = new ProgressRecord(activityId, activity, statusDescription) {ParentActivityId = parentActivityId};
}
private void UpdateCurrentProgressRecordInternal(int count)
{
if (!_stopwatch.IsRunning && TotalCount > 0)
{
_stopwatch.Start();
}
var current = TotalCount > 0 ? $"({count}/{TotalCount}) {_currentOperation}" : _currentOperation;
var pr = _progressRecord.Clone();
pr.CurrentOperation = current;
pr.RecordType = ProgressRecordType.Processing;
if (TotalCount > 0)
{
pr.PercentComplete = GetPercentComplete(count);
pr.SecondsRemaining = GetSecondsRemaining(count);
}
_progressRecord = pr;
}
public void SetCurrentOperation(string currentOperation)
{
_currentOperation = currentOperation;
}
public void UpdateCurrentProgressRecord(int count)
{
UpdateCurrentProgressRecordInternal(count);
}
public ProgressRecord ProgressRecord => _progressRecord;
public ProgressRecord Completed()
{
_stopwatch.Reset();
_progressRecord = _progressRecord.WithRecordType(ProgressRecordType.Completed);
return _progressRecord;
}
private int GetSecondsRemaining(int count)
{
var secondsRemaining = count == 0 ? -1 : (int) ((TotalCount - count)*_stopwatch.ElapsedMilliseconds/1000/count);
return secondsRemaining;
}
private int GetPercentComplete(int count)
{
var percentComplete = count*100/TotalCount;
return percentComplete;
}
public int ActivityId => _progressRecord.ActivityId;
}
class ProgressProjector
{
private readonly Stopwatch _stopWatch;
private int _percentComplete;
public ProgressProjector()
{
_stopWatch = new Stopwatch();
_percentComplete = -1;
}
public void ReportProgress(int percentComplete)
{
if (percentComplete > 100)
{
percentComplete = 100;
}
_percentComplete = percentComplete;
}
public bool IsValid => _percentComplete > 0 && _stopWatch.IsRunning;
public TimeSpan Elapsed => _stopWatch.Elapsed;
public TimeSpan ProjectedTotalTime => new TimeSpan(Elapsed.Ticks * 100 / _percentComplete);
public void Start()
{
_stopWatch.Start();
_percentComplete = 0;
}
public void Stop()
{
_stopWatch.Stop();
}
}
static class ProgressRecordExtension
{
static ProgressRecord CloneProgressRecord(ProgressRecord record)
{
return new ProgressRecord(record.ActivityId, record.Activity, record.StatusDescription)
{
CurrentOperation = record.CurrentOperation,
ParentActivityId = record.ParentActivityId,
SecondsRemaining = record.SecondsRemaining,
PercentComplete = record.PercentComplete,
RecordType = record.RecordType
};
}
public static ProgressRecord Clone(this ProgressRecord record)
{
return CloneProgressRecord(record);
}
public static ProgressRecord WithCurrentOperation(this ProgressRecord record, string currentOperation)
{
var r = CloneProgressRecord(record);
r.CurrentOperation = currentOperation;
return r;
}
public static ProgressRecord WithRecordType(this ProgressRecord record, ProgressRecordType recordType)
{
var r = CloneProgressRecord(record);
r.RecordType = recordType;
return r;
}
public static ProgressRecord WithPercentCompleteAndSecondsRemaining(this ProgressRecord record, int percentComplete, int secondsRemaining)
{
var r = CloneProgressRecord(record);
r.PercentComplete = percentComplete;
r.SecondsRemaining = secondsRemaining;
return r;
}
}
}