Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 328592f

Browse files
code_review: PR #1012
Signed-off-by: leo <longshuang@msn.cn>
1 parent e9d4377 commit 328592f

File tree

5 files changed

+81
-75
lines changed

5 files changed

+81
-75
lines changed

‎src/Commands/Command.cs

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,13 @@
33
using System.Diagnostics;
44
using System.Text;
55
using System.Text.RegularExpressions;
6-
6+
usingSystem.Threading;
77
using Avalonia.Threading;
88

99
namespace SourceGit.Commands
1010
{
1111
public partial class Command
1212
{
13-
public class CancelToken
14-
{
15-
public bool Requested { get; set; } = false;
16-
}
17-
1813
public class ReadToEndResult
1914
{
2015
public bool IsSuccess { get; set; } = false;
@@ -30,55 +25,28 @@ public enum EditorType
3025
}
3126

3227
public string Context { get; set; } = string.Empty;
33-
public CancelTokenCancel { get; set; } = null;
28+
public CancellationTokenCancellationToken { get; set; } = CancellationToken.None;
3429
public string WorkingDirectory { get; set; } = null;
3530
public EditorType Editor { get; set; } = EditorType.CoreEditor; // Only used in Exec() mode
3631
public string SSHKey { get; set; } = string.Empty;
3732
public string Args { get; set; } = string.Empty;
3833
public bool RaiseError { get; set; } = true;
3934
public bool TraitErrorAsOutput { get; set; } = false;
40-
public bool Cancelable { get; } = false;
41-
42-
public Command(bool cancelable = false)
43-
{
44-
Cancelable = cancelable;
45-
}
4635

4736
public bool Exec()
4837
{
4938
var start = CreateGitStartInfo();
5039
var errs = new List<string>();
5140
var proc = new Process() { StartInfo = start };
52-
var isCancelled = false;
5341

5442
proc.OutputDataReceived += (_, e) =>
5543
{
56-
if (Cancel != null && Cancel.Requested)
57-
{
58-
isCancelled = true;
59-
proc.CancelErrorRead();
60-
proc.CancelOutputRead();
61-
if (!proc.HasExited)
62-
proc.Kill(true);
63-
return;
64-
}
65-
6644
if (e.Data != null)
6745
OnReadline(e.Data);
6846
};
6947

7048
proc.ErrorDataReceived += (_, e) =>
7149
{
72-
if (Cancel != null && Cancel.Requested)
73-
{
74-
isCancelled = true;
75-
proc.CancelErrorRead();
76-
proc.CancelOutputRead();
77-
if (!proc.HasExited)
78-
proc.Kill(true);
79-
return;
80-
}
81-
8250
if (string.IsNullOrEmpty(e.Data))
8351
{
8452
errs.Add(string.Empty);
@@ -103,6 +71,15 @@ public bool Exec()
10371
errs.Add(e.Data);
10472
};
10573

74+
if (CancellationToken.CanBeCanceled)
75+
{
76+
CancellationToken.Register(() =>
77+
{
78+
if (_proc != null && !_isDone)
79+
Native.OS.TerminateSafely(_proc);
80+
});
81+
}
82+
10683
try
10784
{
10885
proc.Start();
@@ -115,6 +92,7 @@ public bool Exec()
11592
return false;
11693
}
11794

95+
_isDone = false;
11896
_proc = proc;
11997

12098
int exitCode;
@@ -124,6 +102,7 @@ public bool Exec()
124102
proc.BeginErrorReadLine();
125103
proc.WaitForExit();
126104

105+
_isDone = true;
127106
exitCode = proc.ExitCode;
128107
proc.Close();
129108
}
@@ -132,7 +111,7 @@ public bool Exec()
132111
_proc = null;
133112
}
134113

135-
if (!isCancelled && exitCode != 0)
114+
if (!CancellationToken.IsCancellationRequested && exitCode != 0)
136115
{
137116
if (RaiseError)
138117
{
@@ -166,37 +145,17 @@ public ReadToEndResult ReadToEnd()
166145
};
167146
}
168147

169-
_proc = proc;
170-
171-
try
172-
{
173-
var rs = new ReadToEndResult()
174-
{
175-
StdOut = proc.StandardOutput.ReadToEnd(),
176-
StdErr = proc.StandardError.ReadToEnd(),
177-
};
178-
179-
proc.WaitForExit();
180-
rs.IsSuccess = proc.ExitCode == 0;
181-
proc.Close();
182-
183-
return rs;
184-
}
185-
finally
148+
var rs = new ReadToEndResult()
186149
{
187-
_proc = null;
188-
}
189-
}
190-
191-
public void TryCancel()
192-
{
193-
if (!this.Cancelable)
194-
throw new Exception("Command is not cancelable!");
150+
StdOut = proc.StandardOutput.ReadToEnd(),
151+
StdErr = proc.StandardError.ReadToEnd(),
152+
};
195153

196-
if (_proc is null)
197-
return;
154+
proc.WaitForExit();
155+
rs.IsSuccess = proc.ExitCode == 0;
156+
proc.Close();
198157

199-
Native.OS.TerminateSafely(_proc);
158+
returnrs;
200159
}
201160

202161
protected virtual void OnReadline(string line)
@@ -264,5 +223,6 @@ private ProcessStartInfo CreateGitStartInfo()
264223
private static partial Regex REG_PROGRESS();
265224

266225
private Process _proc = null;
226+
private bool _isDone = false;
267227
}
268228
}

‎src/ViewModels/CommitDetail.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Globalization;
44
using System.IO;
55
using System.Text.RegularExpressions;
6+
using System.Threading;
67
using System.Threading.Tasks;
78

89
using Avalonia.Collections;
@@ -205,6 +206,8 @@ public void Cleanup()
205206
{
206207
_repo = null;
207208
_commit = null;
209+
_cancelSource?.Cancel();
210+
_cancelSource = null;
208211

209212
if (_changes != null)
210213
_changes.Clear();
@@ -217,7 +220,6 @@ public void Cleanup()
217220
_searchChangeFilter = null;
218221
_diffContext = null;
219222
_viewRevisionFileContent = null;
220-
_cancelToken = null;
221223

222224
WebLinks.Clear();
223225
_revisionFiles.Clear();
@@ -644,27 +646,28 @@ private void Refresh()
644646
Dispatcher.UIThread.Invoke(() => SignInfo = signInfo);
645647
});
646648

647-
if (_cancelToken!=null)
648-
_cancelToken.Requested=true;
649+
if (_cancelSourceis{IsCancellationRequested:false})
650+
_cancelSource.Cancel();
649651

650-
_cancelToken = new Commands.Command.CancelToken();
652+
_cancelSource = new CancellationTokenSource();
653+
var cancelToken = _cancelSource.Token;
651654

652655
if (Preferences.Instance.ShowChildren)
653656
{
654657
Task.Run(() =>
655658
{
656659
var max = Preferences.Instance.MaxHistoryCommits;
657-
var cmdChildren = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max) { Cancel = _cancelToken };
660+
var cmdChildren = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max) { CancellationToken = cancelToken };
658661
var children = cmdChildren.Result();
659-
if (!cmdChildren.Cancel.Requested)
662+
if (!cancelToken.IsCancellationRequested)
660663
Dispatcher.UIThread.Post(() => Children.AddRange(children));
661664
});
662665
}
663666

664667
Task.Run(() =>
665668
{
666669
var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0];
667-
var cmdChanges = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { Cancel = _cancelToken };
670+
var cmdChanges = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { CancellationToken = cancelToken };
668671
var changes = cmdChanges.Result();
669672
var visible = changes;
670673
if (!string.IsNullOrWhiteSpace(_searchChangeFilter))
@@ -677,7 +680,7 @@ private void Refresh()
677680
}
678681
}
679682

680-
if (!cmdChanges.Cancel.Requested)
683+
if (!cancelToken.IsCancellationRequested)
681684
{
682685
Dispatcher.UIThread.Post(() =>
683686
{
@@ -823,6 +826,7 @@ private void UpdateRevisionFileSearchSuggestion()
823826
private Repository _repo = null;
824827
private int _activePageIndex = 0;
825828
private Models.Commit _commit = null;
829+
private CancellationTokenSource _cancelSource = null;
826830
private string _fullMessage = string.Empty;
827831
private Models.CommitSignInfo _signInfo = null;
828832
private List<Models.Change> _changes = null;
@@ -831,7 +835,6 @@ private void UpdateRevisionFileSearchSuggestion()
831835
private string _searchChangeFilter = string.Empty;
832836
private DiffContext _diffContext = null;
833837
private object _viewRevisionFileContent = null;
834-
private Commands.Command.CancelToken _cancelToken = null;
835838
private List<string> _revisionFiles = [];
836839
private string _revisionFileSearchFilter = string.Empty;
837840
private bool _isRevisionFileSearchSuggestionOpen = false;

‎src/ViewModels/Fetch.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public Fetch(Repository repo, Models.Remote preferedRemote = null)
5656
SelectedRemote = _repo.Remotes[0];
5757
}
5858

59+
CanCancelInProgress = true;
5960
View = new Views.Fetch() { DataContext = this };
6061
}
6162

@@ -72,13 +73,17 @@ public override Task<bool> Sure()
7273
foreach (var remote in _repo.Remotes)
7374
{
7475
SetProgressDescription($"Fetching remote: {remote.Name}");
75-
new Commands.Fetch(_repo.FullPath, remote.Name, notags, force, SetProgressDescription).Exec();
76+
var cmd = new Commands.Fetch(_repo.FullPath, remote.Name, notags, force, SetProgressDescription);
77+
cmd.CancellationToken = CancelInProgressTokenSource.Token;
78+
cmd.Exec();
7679
}
7780
}
7881
else
7982
{
8083
SetProgressDescription($"Fetching remote: {SelectedRemote.Name}");
81-
new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, notags, force, SetProgressDescription).Exec();
84+
var cmd = new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, notags, force, SetProgressDescription);
85+
cmd.CancellationToken = CancelInProgressTokenSource.Token;
86+
cmd.Exec();
8287
}
8388

8489
CallUIThread(() =>

‎src/ViewModels/Popup.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics.CodeAnalysis;
3+
using System.Threading;
34
using System.Threading.Tasks;
45

56
using Avalonia.Threading;
@@ -14,7 +15,7 @@ public object View
1415
{
1516
get;
1617
set;
17-
}
18+
}=null;
1819

1920
public bool InProgress
2021
{
@@ -28,6 +29,18 @@ public string ProgressDescription
2829
set => SetProperty(ref _progressDescription, value);
2930
}
3031

32+
public bool CanCancelInProgress
33+
{
34+
get;
35+
set;
36+
} = false;
37+
38+
public CancellationTokenSource CancelInProgressTokenSource
39+
{
40+
get;
41+
set;
42+
} = new CancellationTokenSource();
43+
3144
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode")]
3245
public bool Check()
3346
{
@@ -37,6 +50,12 @@ public bool Check()
3750
return !HasErrors;
3851
}
3952

53+
public void CancelInProgress()
54+
{
55+
if (CanCancelInProgress)
56+
CancelInProgressTokenSource.Cancel();
57+
}
58+
4059
public virtual bool CanStartDirectly()
4160
{
4261
return true;

‎src/Views/LauncherPage.axaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,25 @@
9898
<v:PopupRunningStatus Margin="12,8"
9999
Description="{Binding ProgressDescription}"
100100
IsVisible="{Binding InProgress}"/>
101+
102+
<!-- Cancel Button -->
103+
<Border Margin="0,4,0,8">
104+
<Button Classes="flat primary"
105+
Width="100" Height="28"
106+
Padding="0"
107+
HorizontalAlignment="Center"
108+
HorizontalContentAlignment="Center"
109+
VerticalContentAlignment="Center"
110+
Content="{DynamicResource Text.Cancel}"
111+
Command="{Binding CancelInProgress}">
112+
<Button.IsVisible>
113+
<MultiBinding Converter="{x:Static BoolConverters.And}">
114+
<Binding Path="InProgress"/>
115+
<Binding Path="CanCancelInProgress"/>
116+
</MultiBinding>
117+
</Button.IsVisible>
118+
</Button>
119+
</Border>
101120
</StackPanel>
102121
</DataTemplate>
103122
</ContentControl.DataTemplates>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /