Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Async/Await: Leave AsyncLocal<T> context upon task creation

AsyncLocal allows us to keep context data on a async control flow. This is pretty neat since all following resumes (even on another thread) can retrieve and modify the ambient data (AsyncLocal on MSDN).

Is there any way to 'leave' the current async local context for a sub-task and thus create a new one?

AsyncLocal<string> Data = new AsyncLocal<string>();
Data.Value = "One";

Task.Factory.StartNew( () =>
{
    string InnerValue = Data.Value;
    //InnerValue equals to "One", I need it to be null.
} );

In the example above, the inner task shares the AsyncLocal context with the outer control flow. Is there any way to enforce a new context?

Update: in order to solve my issue here, the following worked like a charm (despite the fact that it didn't entirely reset the context):

AsyncLocal<string> Data = new AsyncLocal<string>();
Data.Value = "One";

Task.Factory.StartNew( () =>
{
    Data.Value = null;
    string InnerValue = Data.Value;
    //InnerValue equals to null now.
} );

string OuterValue = Data.Value; //Stays "one" even after the inner change.
like image 825
Simon Mattes Avatar asked Mar 06 '16 12:03

Simon Mattes


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.


1 Answers

You can use ExecutionContext.SuppressFlow:

AsyncLocal<string> Data = new AsyncLocal<string>();
Data.Value = "One";

using (ExecutionContext.SuppressFlow())
{    
    Task.Factory.StartNew( () =>
    {
        string InnerValue = Data.Value;
        //InnerValue is null.
    } );
}

Note that this may have side-effects, such as no longer producing proper stack traces. However, since you ignore the result of StartNew, i.e. you seem to not be interested in actually having a flow, this would be the correct thing to do.

Alternatively, and more in line with the solution in your own update, remember that AsyncLocal is scoped, i.e. if you set the value in a nested async operation, it does not affect the value in your outer function. This means that you can reset AsyncLocals first thing in the nested operation without destroying the values for the outer operation.

like image 133
Sebastian Redl Avatar answered Oct 16 '22 23:10

Sebastian Redl