Skip to content

Commit 66911f9

Browse files
David EllingsworthDavid Ellingsworth
authored andcommitted
Refactor the CustomSynchronizationContext to capture the current context when it is run.
This simplifies the RunSync method and clarifies the context in which the PostCallback is ran.
1 parent ec15969 commit 66911f9

1 file changed

Lines changed: 25 additions & 19 deletions

File tree

src/RestSharp/AsyncHelpers.cs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,9 @@ static class AsyncHelpers {
2525
/// </summary>
2626
/// <param name="task">Callback for asynchronous task to run</param>
2727
static void RunSync(Func<Task> task) {
28-
var currentContext = SynchronizationContext.Current;
2928
var customContext = new CustomSynchronizationContext(task);
3029

31-
try {
32-
SynchronizationContext.SetSynchronizationContext(customContext);
33-
customContext.Run();
34-
}
35-
finally {
36-
SynchronizationContext.SetSynchronizationContext(currentContext);
37-
}
30+
customContext.Run();
3831
}
3932

4033
/// <summary>
@@ -80,26 +73,39 @@ public override void Post(SendOrPostCallback function, object? state) {
8073
/// Enqueues the function to be executed and executes all resulting continuations until it is completely done
8174
/// </summary>
8275
public void Run() {
83-
Post(PostCallback, null);
76+
var currentContext = SynchronizationContext.Current;
77+
78+
try {
79+
SynchronizationContext.SetSynchronizationContext(this);
80+
81+
Post(PostCallback, null);
8482

85-
while (!_done) {
86-
if (_items.TryDequeue(out var task)) {
87-
task.Item1(task.Item2);
88-
if (_caughtException == null) {
89-
continue;
83+
while (!_done) {
84+
if (_items.TryDequeue(out var task)) {
85+
task.Item1(task.Item2);
86+
if (_caughtException == null) {
87+
continue;
88+
}
89+
_caughtException.Throw();
90+
}
91+
else {
92+
_workItemsWaiting.WaitOne();
9093
}
91-
_caughtException.Throw();
92-
}
93-
else {
94-
_workItemsWaiting.WaitOne();
9594
}
9695
}
96+
finally {
97+
SynchronizationContext.SetSynchronizationContext(currentContext);
98+
}
99+
97100

98101
return;
99102

103+
// This method is only called from within this custom context before the loop above.
100104
async void PostCallback(object? _) {
101105
try {
102-
await _task().ConfigureAwait(false);
106+
// Do not call ConfigureAwait(false) here to ensure all continuations are
107+
// queued on this context, not the threadpool.
108+
await _task();
103109
}
104110
catch (Exception exception) {
105111
_caughtException = ExceptionDispatchInfo.Capture(exception);

0 commit comments

Comments
 (0)