none
XNamespace and XName thread safety

    Question

  • The documentation of System.Xml.Linq.XNamespace says:

    XNamespace Atomization

    XNamespace objects are guaranteed to be atomized; that is, if two XNamespace objects have exactly the same URI, they will share the same instance. The equality and comparison operators are provided explicitly for this purpose.

    However, it also says:

    Thread Safety

    Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

    Suppose two threads call var ns = XNamespace.Get("urn:uuid:1f6332d1-d867-4c54-bbf5-2de723c9eabc") or use the equivalent String-to-XNamespace conversion operator.  According to the first point above, both threads get the same XNamespace object.  Then, both threads call ns.GetName("coax").  Because GetName is an instance member, this call is not guaranteed to be thread safe, according to the second point above.  However, if it is not thread safe, then I don't see how programs can ever use XNamespace objects correctly.

    Is it correct to assume that the instance members of XNamespace and XName are actually thread safe, even though the documentation says this is not guaranteed?

    Tuesday, October 08, 2013 6:27 PM

All replies

  • Hello,

    According to the senond point, it says that any public static (Shared in Visual Basic) members of this type are thread safe. However, the instance members of XNamespace and XName are not public static, so it may be thread safe or not.

    As its secon description statement, we can not judge the type which is not public static is thread safe or not.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, October 10, 2013 7:54 AM
    Moderator
  • Thanks for the reply.  Are you then saying that the XNamespace.GetName calls in the following program might not work correctly?

    namespace ThreadSafetySample
    {
        using System.Collections.Generic;
        using System.Diagnostics;
        using System.Threading;
        using System.Xml.Linq;
    
        internal class Program
        {
            internal static void Main()
            {
                // Start four threads, each of which calls Program.Fun.
                var threads = new List<Thread>();
                for (int i = 0; i < 4; i++)
                {
                    var thread = new Thread(Program.Fun);
                    threads.Add(thread);
                    thread.Start();
                }
    
                // Each thread will run for one second and then exit.
                // Wait for them.
                foreach (var thread in threads)
                {
                    thread.Join();
                }
            }
    
            private static void Fun()
            {
                // According to the documentation of XNamespace, the instances are
                // atomized, so the following XNamespace.Get call will return the
                // same XNamespace instance in every thread.
                XNamespace ns = XNamespace.Get("urn:uuid:1f6332d1-d867-4c54-bbf5-2de723c9eabc");
    
                // Loop until one second has elapsed.
                var stopwatch = Stopwatch.StartNew();
                while (stopwatch.ElapsedMilliseconds < 1000)
                {
                    // XNamespace.GetName is an instance member.
                    // According to the documentation of XNamespace,
                    // instance members are not guaranteed to be thread safe.
                    // Is there a problem because the other threads are also
                    // calling ns.GetName at the same time?
                    ns.GetName("coax");
                }
            }
        }
    }
    

    If so, how should I change Program.Fun in order to make it safe to call from multiple threads in parallel?

    In general, I can't know which XNamespace instances the other threads of the process are using, because third-party code may call XNamespace.Get and get the same instance as my code got.  If the instance members of XNamespace are really not thread safe, that makes the class rather useless.  That's why I thought the instance members might be thread safe even though the documentation says otherwise.

    Thursday, October 10, 2013 1:32 PM