c# - Flow context/state through generated continuations -
first, context (pardon pun). consider following 2 async methods:
public async task async1() { prework(); await async2(); postwork(); } public async task async2() { await async3(); }
thanks async
, await
keywords, creates illusion of nice simple call stack:
- async1
- prework
- async2
- async3
- postwork
but, if understand correctly, in generated code call postwork
tacked on continuation async2
task, @ runtime flow of execution more this:
- async1
- prework
- async2
- async3
- postwork
- async3
(and it's more complicated that, because in reality use of async
, await
causes compiler generate state machines each async method, might able ignore detail question)
now, my question: there way flow sort of context through these auto-generated continuations, such time hit postwork
, have accumulated state async1
, async2
?
i can similar want tools asynclocal , callcontext.logicalsetdata, aren't quite need because contexts "rolled back" work way async chain. example, calling async1
in following code print "1,3", not "1,2,3":
private static readonly asynclocal<immutablequeue<string>> _asynclocal = new asynclocal<immutablequeue<string>>(); public async task async1() { _asynclocal.value = immutablequeue<string>.empty.enqueue("1"); await async2(); _asynclocal.value = _asynclocal.value.enqueue("3"); console.writeline(string.join(",", _asynclocal.value)); } public async task async2() { _asynclocal.value = _asynclocal.value.enqueue("2"); await async3(); }
i understand why prints "1,3" (the execution context flows down async2
not async1
) isn't i'm looking for. want accumulate state through actual execution chain, such i'm able print "1,2,3" @ end because actual way in methods executed leading call console.writeline
.
note don't want blindly accumulate state across async work, want accumulate state causally related. in scenario want print "1,2,3" because "2" came dependent (awaited) task. if instead call async2
fire-and-forget task wouldn't expect see "2" because execution not in actual chain leading console.writeline
.
edit: not want solve problem passing around parameters , return values because need generic solution work across large code base without having modify every method pass around metadata.
Comments
Post a Comment