Skip to content

Commit b4580ec

Browse files
authored
Merge pull request #452 from GeneralLibrary/fix/async-anti-patterns
fix: eliminate sync-over-async anti-patterns (.GetAwaiter().GetResult())
2 parents 0bdfe24 + fa5deb6 commit b4580ec

16 files changed

Lines changed: 58 additions & 83 deletions

File tree

src/c#/ExtensionTest/Communication/ExtensionHttpClientTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void 构造函数_ServerUrl末尾斜杠被Trim()
8181
}
8282

8383
[Fact]
84-
public void 构造函数_Scheme和Token非空_设置AuthorizationHeader()
84+
public async Task 构造函数_Scheme和Token非空_设置AuthorizationHeader()
8585
{
8686
var handler = new Mock<HttpMessageHandler>();
8787
HttpRequestMessage? capturedRequest = null;
@@ -98,7 +98,7 @@ public void 构造函数_Scheme和Token非空_设置AuthorizationHeader()
9898
using var httpClient = new HttpClient(handler.Object);
9999
using var client = new ExtensionHttpClient("http://test", "Bearer", "my-token", httpClient);
100100

101-
client.QueryExtensionsAsync(new ExtensionQueryDTO()).GetAwaiter().GetResult();
101+
await client.QueryExtensionsAsync(new ExtensionQueryDTO());
102102

103103
Assert.NotNull(capturedRequest);
104104
Assert.NotNull(capturedRequest!.Headers.Authorization);
@@ -107,7 +107,7 @@ public void 构造函数_Scheme和Token非空_设置AuthorizationHeader()
107107
}
108108

109109
[Fact]
110-
public void 构造函数_Scheme为空_不设置Authorization()
110+
public async Task 构造函数_Scheme为空_不设置Authorization()
111111
{
112112
var handler = new Mock<HttpMessageHandler>();
113113
HttpRequestMessage? capturedRequest = null;
@@ -123,7 +123,7 @@ public void 构造函数_Scheme为空_不设置Authorization()
123123

124124
using var httpClient = new HttpClient(handler.Object);
125125
using var client = new ExtensionHttpClient("http://test", "", "", httpClient);
126-
client.QueryExtensionsAsync(new ExtensionQueryDTO()).GetAwaiter().GetResult();
126+
await client.QueryExtensionsAsync(new ExtensionQueryDTO());
127127

128128
Assert.Null(capturedRequest!.Headers.Authorization);
129129
}

src/c#/GeneralUpdate.Bowl/Bowl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public static void Launch(MonitorParameter? monitorParameter = null)
280280
}
281281

282282
var bowl = new Bowl();
283-
bowl.LaunchAsync(context).ConfigureAwait(false).GetAwaiter().GetResult();
283+
bowl.LaunchAsync(context).GetAwaiter().GetResult();
284284
}
285285

286286
/// <summary>

src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStra
174174
finally
175175
{
176176
// Dispose HubDownloadSource if it was started
177-
if (roleStrategy is ClientUpdateStrategy cs && cs.DownloadSource is IDisposable d)
178-
d.Dispose();
177+
if (roleStrategy is ClientUpdateStrategy cs && cs.DownloadSource is IAsyncDisposable ad)
178+
await ad.DisposeAsync();
179179
_cts?.Dispose();
180180
_cts = null;
181181
}

src/c#/GeneralUpdate.Core/Download/Sources/HubDownloadSource.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace GeneralUpdate.Core.Download.Sources;
1515
/// SignalR Hub download source — receives update push notifications
1616
/// and converts them to DownloadAssets for the orchestrator.
1717
/// </summary>
18-
public class HubDownloadSource : IDownloadSource, IDisposable
18+
public class HubDownloadSource : IDownloadSource, IAsyncDisposable
1919
{
2020
private readonly string _hubUrl;
2121
private readonly string? _token;
@@ -77,8 +77,9 @@ public async Task<IReadOnlyList<DownloadAsset>> ListAsync(CancellationToken toke
7777
return _assets.ToList();
7878
}
7979

80-
public void Dispose()
80+
public async ValueTask DisposeAsync()
8181
{
82-
_hub?.DisposeAsync().GetAwaiter().GetResult();
82+
if (_hub != null)
83+
await _hub.DisposeAsync();
8384
}
8485
}

src/c#/GeneralUpdate.Core/Strategy/AbstractStrategy.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ public abstract class AbstractStrategy : IStrategy
3434
/// <summary>DiffPipeline for parallel patch application with progress reporting.</summary>
3535
public DiffPipeline? DiffPipeline { get; set; }
3636

37-
public virtual void Execute() => throw new NotImplementedException();
38-
39-
public virtual void StartApp() => throw new NotImplementedException();
37+
public virtual Task StartAppAsync() => throw new NotImplementedException();
4038

4139
public virtual async Task ExecuteAsync()
4240
{
@@ -72,7 +70,7 @@ await VersionService.Report(_configinfo.ReportUrl
7270

7371
Clear(patchPath);
7472
Clear(_configinfo.TempPath);
75-
OnExecuteComplete();
73+
await OnExecuteCompleteAsync();
7674
}
7775
catch (Exception e)
7876
{
@@ -120,9 +118,9 @@ protected virtual PipelineContext CreatePipelineContext(VersionInfo version, str
120118
/// Called after ExecuteAsync completes successfully.
121119
/// Override this method to add platform-specific post-execution logic.
122120
/// </summary>
123-
protected virtual void OnExecuteComplete()
121+
protected virtual Task OnExecuteCompleteAsync()
124122
{
125-
// Default implementation does nothing
123+
return Task.CompletedTask;
126124
}
127125

128126
/// <summary>

src/c#/GeneralUpdate.Core/Strategy/ClientUpdateStrategy.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,6 @@ public async Task ExecuteAsync()
7373
}
7474
}
7575

76-
public void Execute()
77-
{
78-
ExecuteAsync().GetAwaiter().GetResult();
79-
}
80-
8176
private IDirtyStrategy? _pendingDirtyStrategy;
8277

8378
/// <summary>Sets the directory-level dirty strategy on the underlying OS-level strategy for differential patch updates.
@@ -104,9 +99,10 @@ public void SetDiffPipeline(DiffPipeline? diffPipeline)
10499
abs.DiffPipeline = diffPipeline;
105100
}
106101

107-
public void StartApp()
102+
public async Task StartAppAsync()
108103
{
109-
_osStrategy?.StartApp();
104+
if (_osStrategy != null)
105+
await _osStrategy.StartAppAsync();
110106
}
111107

112108
/// <summary>Register a precheck callback invoked when update info is available.</summary>

src/c#/GeneralUpdate.Core/Strategy/IStrategy.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,12 @@ public interface IStrategy
1111
/// <summary>
1212
/// Execution strategy.
1313
/// </summary>
14-
void Execute();
14+
Task ExecuteAsync();
1515

1616
/// <summary>
1717
/// After the update is complete.
1818
/// </summary>
19-
void StartApp();
20-
21-
/// <summary>
22-
/// Execution strategy.
23-
/// </summary>
24-
Task ExecuteAsync();
19+
Task StartAppAsync();
2520

2621
/// <summary>
2722
/// Create a strategy.

src/c#/GeneralUpdate.Core/Strategy/LinuxStrategy.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics;
3+
using System.Threading.Tasks;
34
using GeneralUpdate.Core;
45
using GeneralUpdate.Core.Configuration;
56
using GeneralUpdate.Core.Event;
@@ -26,18 +27,13 @@ protected override PipelineBuilder BuildPipeline(PipelineContext context)
2627
return builder;
2728
}
2829

29-
public override void Execute()
30-
{
31-
ExecuteAsync().Wait();
32-
}
33-
34-
protected override void OnExecuteComplete()
30+
protected override async Task OnExecuteCompleteAsync()
3531
{
3632
GeneralTracer.Info("GeneralUpdate.Core.LinuxStrategy.OnExecuteComplete: all versions processed, starting application.");
37-
StartApp();
33+
await StartAppAsync();
3834
}
3935

40-
public override void StartApp()
36+
public override async Task StartAppAsync()
4137
{
4238
try
4339
{
@@ -59,7 +55,7 @@ public override void StartApp()
5955
{
6056
GeneralTracer.Info("GeneralUpdate.Core.LinuxStrategy.StartApp: releasing tracer and terminating updater process.");
6157
GeneralTracer.Dispose();
62-
GracefulExit.CurrentProcessAsync().GetAwaiter().GetResult();
58+
await GracefulExit.CurrentProcessAsync();
6359
}
6460
}
6561

src/c#/GeneralUpdate.Core/Strategy/MacStrategy.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@ namespace GeneralUpdate.Core.Strategy;
1111
/// <summary>macOS update strategy — follows Linux conventions.</summary>
1212
public class MacStrategy : AbstractStrategy
1313
{
14-
public override void Execute() => ExecuteAsync().GetAwaiter().GetResult();
15-
1614
public override async Task ExecuteAsync()
1715
{
1816
GeneralTracer.Info("MacStrategy: executing pipeline");
1917
await base.ExecuteAsync().ConfigureAwait(false);
2018
}
2119

22-
public override void StartApp()
20+
public override async Task StartAppAsync()
2321
{
2422
try
2523
{
@@ -42,7 +40,7 @@ public override void StartApp()
4240
{
4341
GeneralTracer.Info("MacStrategy.StartApp: releasing tracer and terminating updater process.");
4442
GeneralTracer.Dispose();
45-
GracefulExit.CurrentProcessAsync().GetAwaiter().GetResult();
43+
await GracefulExit.CurrentProcessAsync();
4644
}
4745
}
4846

src/c#/GeneralUpdate.Core/Strategy/OSSUpdateStrategy.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ private async Task ExecuteUpgradeAsync()
182182
await SafeOnBeforeStartAppAsync(ctx).ConfigureAwait(false);
183183

184184
GeneralTracer.Debug("OSSUpdateStrategy (upgrade): launching main app.");
185-
StartApp();
185+
await StartAppAsync();
186186
}
187187
catch (Exception ex)
188188
{
@@ -197,19 +197,18 @@ private async Task ExecuteUpgradeAsync()
197197
}
198198
}
199199

200-
public void Execute() => ExecuteAsync().GetAwaiter().GetResult();
201-
202-
public void StartApp()
200+
public Task StartAppAsync()
203201
{
204202
var appName = _configInfo?.MainAppName ?? _configInfo?.AppName;
205-
if (string.IsNullOrEmpty(appName)) return;
203+
if (string.IsNullOrEmpty(appName)) return Task.CompletedTask;
206204

207205
var appPath = Path.Combine(_appPath, appName);
208206
if (!File.Exists(appPath))
209207
throw new FileNotFoundException($"Application not found: {appPath}");
210208

211209
Process.Start(appPath);
212210
GeneralTracer.Debug("OSSUpdateStrategy: main application started.");
211+
return Task.CompletedTask;
213212
}
214213

215214
#region Helpers

0 commit comments

Comments
 (0)