private async Task RunWorker(CancellationToken ct) {
TaskUtilities.AssertIsOnBackgroundThread();
// Spin until the worker task is registered.
while (_runTask == null) {
await Task.Yield();
}
try {
var message = await ReceiveMessageAsync(ct);
if (message == null || !message.IsNotification || message.Name != "!Microsoft.R.Host") {
throw ProtocolError($"Microsoft.R.Host handshake expected:", message);
}
var protocolVersion = message.GetInt32(0, "protocol_version");
if (protocolVersion != 1) {
throw ProtocolError($"Unsupported RHost protocol version:", message);
}
var rVersion = message.GetString(1, "R_version");
await _callbacks.Connected(rVersion);
message = await RunLoop(ct);
if (message != null) {
throw ProtocolError($"Unexpected host response message:", message);
}
} finally {
// Signal cancellation to any callbacks that haven't returned yet.
_cts.Cancel();
await _callbacks.Disconnected();
}
}