You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AsyncLocal is a really powerful tool, and is great for allowing static access to contextual information.
However it has its nuances and pitfalls.
Correct me if I'm wrong, but currently, AsyncLocal can only be set within a parent async method, and descendants of that method can access those AsyncLocal values.
The reverse is not possible, you cannot set an AsyncLocal value in a child and retrieve it in the parent.
And the same for sibling methods.
If possible, it would be powerful to provide an object such as AsyncLocalContext that would allow setting values in other places as if it was set in the parent. The context could be generated by the parent, and then passed wherever to set values as if the parent set them.
If you don't want to share the context, then by not generating an object to be passed around, it should behave exactly as it does today.
I believe this could lead to more powerful and complex usages that could drive frameworks and such.
publicclassMyClass{privatestaticreadonlyAsyncLocal<string>_asyncLocals=new();publicasync Task ParentMethod(){// This contains the context as if AsyncLocal.Value was set from `ParentMethod`varasyncLocalContext= AsyncLocalContext.Create();await DoSomething(asyncLocalContext);varvalue= _asyncLocals.Value;// Returns "Foo!" because it was set as if it was in the parents context}publicasync Task DoSomething(AsyncLocalContextasyncLocalContext){varvalue=await GetValue();// Returns "Foo!"// Setting it within the context is as if ParentMethod had set it, so it can be retrieved by the parent, and/or descents of the parent
asyncLocalContext.Execute(()=> _asyncLocals.Value =value);}}
I'm writing TUnit, a testing framework, and it's not uncommon for users to want to interact with AsyncLocals, especially if they're wanting to use Asp.Net etc. with Activities, or HttpContextAccessor.
I could expose this context to users, giving them the freedom to set values wherever if they so wish.
Currently as a workaround I have to have my parent method execute any 'set up hooks', and they have to be Synchronous void methods so they inherit the parent context, leading to an overly complex and ugly method, and if I was to refactor it into separate method calls, it'd break for users because they wouldn't be considered a parent method so they'd not be able to set the AsyncLocal values properly.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
AsyncLocal is a really powerful tool, and is great for allowing static access to contextual information.
However it has its nuances and pitfalls.
Correct me if I'm wrong, but currently, AsyncLocal can only be set within a parent async method, and descendants of that method can access those AsyncLocal values.
The reverse is not possible, you cannot set an AsyncLocal value in a child and retrieve it in the parent.
And the same for sibling methods.
If possible, it would be powerful to provide an object such as
AsyncLocalContext
that would allow setting values in other places as if it was set in the parent. The context could be generated by the parent, and then passed wherever to set values as if the parent set them.If you don't want to share the context, then by not generating an object to be passed around, it should behave exactly as it does today.
I believe this could lead to more powerful and complex usages that could drive frameworks and such.
I'm imagining an API like this:
Usage:
I'm writing TUnit, a testing framework, and it's not uncommon for users to want to interact with AsyncLocals, especially if they're wanting to use Asp.Net etc. with Activities, or HttpContextAccessor.
I could expose this context to users, giving them the freedom to set values wherever if they so wish.
Currently as a workaround I have to have my parent method execute any 'set up hooks', and they have to be Synchronous void methods so they inherit the parent context, leading to an overly complex and ugly method, and if I was to refactor it into separate method calls, it'd break for users because they wouldn't be considered a parent method so they'd not be able to set the AsyncLocal values properly.
Example is here: https://github.com/thomhurst/TUnit/blob/cd4a9da54204aee3896d9ab17e53396249c642c1/TUnit.Engine/Services/SingleTestExecutor.cs#L94
If this is already possible someone please educate me! 😄
Beta Was this translation helpful? Give feedback.
All reactions