internal override void TryAlt(ref Worker wr, int i, Cont <X> xK, Else xE) { var pk = xE.pk; var nk = Pick.ClaimAndAddNack(pk, i); if (null != nk) { var cts = new CancellationTokenSource(); Task <X> xT; try { xT = this.Start(cts.Token); } catch (Exception e) { Pick.PickClaimedAndSetNacks(ref wr, i, pk); cts.Dispose(); Handler.DoHandle(xK, ref wr, e); return; } if (TaskStatus.RanToCompletion == xT.Status) { Pick.PickClaimedAndSetNacks(ref wr, i, pk); cts.Dispose(); Cont.Do(xK, ref wr, xT.Result); } else { var state = new TaskToAltAwaiter <X>(cts, pk, i, xT, xK, wr.Scheduler); nk.UnsafeAddReader(state); Pick.Unclaim(pk); var j = i + 1; nk.I1 = j; xT.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(state.Ready); xE.TryElse(ref wr, j); } } }
internal override void TryAlt(ref Worker wr, int i, Cont <X> xK, Else xE) { var pk = xE.pk; var cb = new AltCallback <X>(wr.Scheduler, this, xK, pk, -1); var nk = Pick.ClaimAndAddNack(pk, i); if (null != nk) { try { cb.iar = DoBegin(StaticData.workAsyncCallback, cb); } catch (Exception e) { Pick.PickClaimedAndSetNacks(ref wr, i, pk); Handler.DoHandle(xK, ref wr, e); return; } var m = cb.me; if (0 <= m || m != Interlocked.CompareExchange(ref cb.me, i, m)) { Pick.PickClaimedAndSetNacks(ref wr, i, pk); Cont.Do(xK, ref wr, DoEnd(cb.iar)); } else { nk.UnsafeAddReader(cb); Pick.Unclaim(pk); var j = i + 1; nk.I1 = j; xE.TryElse(ref wr, j); } } }