static Task?BeginSendRemainderInBackground(PooledMultiplexer @this, RespConnection connection, List <IBatchedOperation> values, CancellationToken cancellationToken) { return(connection.PreferSync ? Task.Run(() => { var len = values.Count; try { for (int i = 1; i < len; i++) { Send(@this, connection, values[i], flush: i == len - 1); } } catch (Exception ex) { connection.Doom(); Debug.WriteLine(ex.Message); } }) : Task.Run(async() => { var len = values.Count; try { for (int i = 1; i < len; i++) { await SendAsync(@this, connection, values[i], cancellationToken, flush: i == len - 1).ConfigureAwait(false); } } catch (Exception ex) { connection.Doom(); Debug.WriteLine(ex.Message); } })); }
internal async Task CallAsync(RespConnection connection, List <IBatchedOperation> operations, CancellationToken cancellationToken) { try { int len = operations.Count; if (len == 0) { return; } // push the fisrt *before* we context-switch; the rest can wait await SendAsync(this, connection, operations[0], cancellationToken, true).ConfigureAwait(false); Task?bgSend = len == 1 ? null : BeginSendRemainderInBackground(this, connection, operations, default); foreach (var op in operations) // then receive all { using var response = await connection.ReceiveAsync().ConfigureAwait(false); try { response.Value.ThrowIfError(); op.ProcessResponse(response.Value); } catch (Exception ex) { op.TrySetException(ex); } } if (bgSend != null) { Wait(bgSend); } } catch (Exception ex) { connection.Doom(); foreach (var op in operations) // fault anything that is left after a global explosion { op.TrySetException(ex); } } }