Skip to content

Commit d8b2bf7

Browse files
authored
Code Quality: Improved performance of Git operations (#14688)
1 parent 580ed86 commit d8b2bf7

File tree

2 files changed

+17
-37
lines changed

2 files changed

+17
-37
lines changed

src/Files.App/App.xaml.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,6 @@ await SafetyExtensions.IgnoreExceptions(async () =>
317317
},
318318
Logger);
319319

320-
// Dispose git operations' thread
321-
GitHelpers.TryDispose();
322-
323320
// Destroy cached properties windows
324321
FilePropertiesHelpers.DestroyCachedWindows();
325322
AppModel.IsMainWindowClosed = true;

src/Files.App/Utils/Git/GitHelpers.cs

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ internal static class GitHelpers
4444
? CLIENT_ID_SECRET
4545
: string.Empty;
4646

47-
private static ThreadWithMessageQueue? _owningThread;
48-
49-
private static int _activeOperationsCount = 0;
47+
private static readonly SemaphoreSlim GitOperationSemaphore = new SemaphoreSlim(1, 1);
5048

5149
private static bool _IsExecutingGitAction;
5250
public static bool IsExecutingGitAction
@@ -66,14 +64,6 @@ private set
6664

6765
public static event EventHandler? GitFetchCompleted;
6866

69-
public static void TryDispose()
70-
{
71-
var threadToDispose = _owningThread;
72-
_owningThread = null;
73-
Interlocked.Exchange(ref _activeOperationsCount, 0);
74-
threadToDispose?.Dispose();
75-
}
76-
7767
public static string? GetGitRepositoryPath(string? path, string root)
7868
{
7969
if (string.IsNullOrEmpty(root))
@@ -125,7 +115,7 @@ public static async Task<BranchItem[]> GetBranchesNames(string? path)
125115
if (string.IsNullOrWhiteSpace(path) || !Repository.IsValid(path))
126116
return Array.Empty<BranchItem>();
127117

128-
var (result, returnValue) = await PostMethodToThreadWithMessageQueueAsync<(GitOperationResult, BranchItem[])>(() =>
118+
var (result, returnValue) = await DoGitOperationAsync<(GitOperationResult, BranchItem[])>(() =>
129119
{
130120
var branches = Array.Empty<BranchItem>();
131121
var result = GitOperationResult.Success;
@@ -157,7 +147,7 @@ public static async Task<BranchItem[]> GetBranchesNames(string? path)
157147
if (string.IsNullOrWhiteSpace(path) || !Repository.IsValid(path))
158148
return null;
159149

160-
var (_, returnValue) = await PostMethodToThreadWithMessageQueueAsync<(GitOperationResult, BranchItem?)>(() =>
150+
var (_, returnValue) = await DoGitOperationAsync<(GitOperationResult, BranchItem?)>(() =>
161151
{
162152
BranchItem? head = null;
163153
try
@@ -179,7 +169,7 @@ public static async Task<BranchItem[]> GetBranchesNames(string? path)
179169
}
180170

181171
return (GitOperationResult.Success, head);
182-
});
172+
}, true);
183173

184174
return returnValue;
185175
}
@@ -228,7 +218,7 @@ public static async Task<bool> Checkout(string? repositoryPath, string? branch)
228218
}
229219
}
230220

231-
var result = await PostMethodToThreadWithMessageQueueAsync<GitOperationResult>(() =>
221+
var result = await DoGitOperationAsync<GitOperationResult>(() =>
232222
{
233223
try
234224
{
@@ -306,7 +296,7 @@ public static async Task DeleteBranchAsync(string? repositoryPath, string? activ
306296

307297
IsExecutingGitAction = true;
308298

309-
await PostMethodToThreadWithMessageQueueAsync<GitOperationResult>(() =>
299+
await DoGitOperationAsync<GitOperationResult>(() =>
310300
{
311301
try
312302
{
@@ -363,7 +353,7 @@ public static async void FetchOrigin(string? repositoryPath)
363353
IsExecutingGitAction = true;
364354
});
365355

366-
await PostMethodToThreadWithMessageQueueAsync<GitOperationResult>(() =>
356+
await DoGitOperationAsync<GitOperationResult>(() =>
367357
{
368358
var result = GitOperationResult.Success;
369359
try
@@ -422,7 +412,7 @@ public static async Task PullOriginAsync(string? repositoryPath)
422412
IsExecutingGitAction = true;
423413
});
424414

425-
var result = await PostMethodToThreadWithMessageQueueAsync<GitOperationResult>(() =>
415+
var result = await DoGitOperationAsync<GitOperationResult>(() =>
426416
{
427417
try
428418
{
@@ -508,7 +498,7 @@ public static async Task PushToOriginAsync(string? repositoryPath, string? branc
508498
b => b.UpstreamBranch = branch.CanonicalName);
509499
}
510500

511-
var result = await PostMethodToThreadWithMessageQueueAsync<GitOperationResult>(() =>
501+
var result = await DoGitOperationAsync<GitOperationResult>(() =>
512502
{
513503
try
514504
{
@@ -830,29 +820,22 @@ private static bool IsAuthorizationException(Exception ex)
830820
ex.Message.Contains("authentication replays", StringComparison.OrdinalIgnoreCase);
831821
}
832822

833-
private static void DisposeIfFinished()
823+
private static async Task<T?> DoGitOperationAsync<T>(Func<object> payload, bool useSemaphore = false)
834824
{
835-
if (Interlocked.Decrement(ref _activeOperationsCount) == 0)
836-
TryDispose();
837-
}
838-
839-
private static async Task<T?> PostMethodToThreadWithMessageQueueAsync<T>(Func<object> payload)
840-
{
841-
T? returnValue = default;
842-
843-
Interlocked.Increment(ref _activeOperationsCount);
844-
_owningThread ??= new ThreadWithMessageQueue();
825+
if (useSemaphore)
826+
await GitOperationSemaphore.WaitAsync();
827+
else
828+
await Task.Yield();
845829

846830
try
847831
{
848-
returnValue = await _owningThread.PostMethod<T>(payload);
832+
return (T)payload();
849833
}
850834
finally
851835
{
852-
DisposeIfFinished();
836+
if (useSemaphore)
837+
GitOperationSemaphore.Release();
853838
}
854-
855-
return returnValue;
856839
}
857840
}
858841
}

0 commit comments

Comments
 (0)