1

Running the bellow code you can see that there is a different between CallContext and AsyncLocal.

using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace AsyncLocalIsDifferentThanCallContext
{
    class Program
    {
        public static AsyncLocal<int> AsyncLocal = new AsyncLocal<int>();

        public static int CallContextValue
        {
            get
            {
                var data = CallContext.GetData("CallContextValue");
                if (data == null)
                    return 0;
                return (int) data;
            }
            set { CallContext.SetData("CallContextValue", value); }
        }

        static void Main(string[] args)
        {
            AsyncLocal.Value = 1;
            CallContextValue = 1;
            new Thread(() =>
            {
                Console.WriteLine("From thread AsyncLocal: " + AsyncLocal.Value); // Should be 0 but is 1
                Console.WriteLine("From thread CallContext: " + CallContextValue); // Value is 0, as it should be
            }).Start();
            Console.WriteLine("Main AsyncLocal: " + AsyncLocal.Value);
            Console.WriteLine("Main CallContext: " + CallContextValue);
        }
    }
}

Can you explain why?

I expected the value of AsyncLocal to be unique per thread as the documentation says it should behave and as CallContext behaves.

Fitzchak Yitzchaki
  • 9,095
  • 12
  • 56
  • 96
  • Why would you expect different values? The object you are using is static so just 1 instance can exist of this object. You set the value of this object to a specific value. And then get and print this value, the only thing is you do the very same thing in different threads. I think your expectance is disturbed by using static variables. Read up on static variables here: http://stackoverflow.com/questions/10795502/what-is-the-use-of-static-variable-in-c-when-to-use-it-why-cant-i-declare-th – Totumus Maximus Jan 24 '17 at 10:25
  • My understanding that AsyncLocal should replace CallContext on .net core (as there is no CallContext there) and it should hold a value unique to the thread. Also see the link to the documentation. – Fitzchak Yitzchaki Jan 24 '17 at 11:03
  • There's no task in your example, which is thread based. `AsyncLocal` isn't relevant to anything you are doing here. – Jon Hanna Jan 24 '17 at 13:53
  • Use LogicalGet/SetData() instead. Although it isn't exactly clear what the point might be. – Hans Passant Jan 24 '17 at 14:01

1 Answers1

1

You thinking of ThreadLocal? AsyncLocal can flow across threads as it says

Because the task-based asynchronous programming model tends to abstract the use of threads, AsyncLocal instances can be used to persist data across threads.

Ben Adams
  • 3,281
  • 23
  • 26