Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Use ConfigureAwait(false) throughout RHost & RSession code #206

Merged
merged 1 commit into from
Oct 15, 2015
Merged

Use ConfigureAwait(false) throughout RHost & RSession code #206

merged 1 commit into from
Oct 15, 2015

Conversation

int19h
Copy link
Contributor

@int19h int19h commented Oct 15, 2015

Use ConfigureAwait(false) throughout RHost & RSession code to avoid unnecessary thread affinity, and prevent deadlocks when async methods are called synchronously from the UI thread.

…nnecessary thread affinity, and prevent deadlocks when async methods are called synchronously from the UI thread.
@int19h
Copy link
Contributor Author

int19h commented Oct 15, 2015

Please hit Merge if it looks okay.

crwilcox added a commit that referenced this pull request Oct 15, 2015
Use ConfigureAwait(false) throughout RHost & RSession code
@crwilcox crwilcox merged commit 55d5a0b into microsoft:master Oct 15, 2015
@@ -58,17 +58,17 @@ public sealed class RHost : IDisposable, IRExpressionEvaluator {
var uri = new Uri("ws://localhost:" + DefaultPort);
for (int i = 0; ; ++i) {
try {
await _socket.ConnectAsync(uri, ct);
await _socket.ConnectAsync(uri, ct).ConfigureAwait(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConfigureAwait(true) posts continuation after await into SyncContext if its type is different from base SynchronizationContext type, or into TaskScheduler if is different from TaskScheduler.Default. Otherwise it is scheduled into default TaskScheduler.
ConfigureAwait(false) always schedules continuation after await into default TaskScheduler.

Specifying ConfigureAwait doesn't guarantee that UI thread will not be blocked:

private async Task M1() {
    await Task.Yield();
    while (!_tcs.Task.IsCompleted) { }
}

 // Blocks UI thread
private async void Button_OnClick(object sender, RoutedEventArgs e) {
    // Here we are in UI thread
    await M1().ConfigureAwait(false);
    // Here we are in background ThreadPool thread
}

 // Doesn't block UI thread
private async void Button_OnClick(object sender, RoutedEventArgs e) {
    // Here we are in UI thread
    await Task.Run(() => M1()).ConfigureAwait(true);
    // Here we are in UI thread
}

I'll revert this change and add Task.Run call to RSessionEvaluation.EvaluateAsync to insure that it will not freeze UI if called from UI thread

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants