How to detect cross thread access in .NET (enforce thread affinity)?

后端 未结 3 1920
耶瑟儿~
耶瑟儿~ 2021-02-06 09:20

I\'m writing a special data structure that will be available in a .NET library and one of the features of this data structure is that is will be thread safe provided that only o

相关标签:
3条回答
  • 2021-02-06 09:30

    Could you not require the Read and Write methods take a thread or thread ID? Then you can just compare against the one that called it first, and if it doesn't match, throw an exception or return an error code, or ignore the request.

    Otherwise, what you propose should work also. You need only compare the thread IDs.

    0 讨论(0)
  • 2021-02-06 09:39

    Rather than compare thread ID's you should store the ambient Thread in your class during construction.

    class SingleThreadedClass
    {
        private Thread ownerThread;
    
        public SingleThreadedClass()
        {
            this.ownerThread = Thread.CurrentThread;
        }
    
        public void Read(...)
        {
            if (Thread.CurrentThread != this.ownerThread)
                throw new InvalidOperationException();
        }
    
        public void TakeOwnership()
        {
            this.ownerThread = Thread.CurrentThread;
        }
    }
    
    0 讨论(0)
  • 2021-02-06 09:45

    When I run into this situation I use a class I wrote called ThreadAffinity. It's entire purpose is to record the current thread and throw on invalid accesses from a different thread. You have to manually do the check but it encapsulates the small amount of work for you.

    class Foo {
      ThreadAffinity affinity = new ThreadAffinity();
    
      public string SomeProperty {
        get { affinity.Check(); return "Somevalue"; }
      }
    }
    

    Class

    [Immutable]
    public sealed class ThreadAffinity
    {
        private readonly int m_threadId;
    
        public ThreadAffinity()
        {
            m_threadId = Thread.CurrentThread.ManagedThreadId;
        }
    
        public void Check()
        {
            if (Thread.CurrentThread.ManagedThreadId != m_threadId)
            {
                var msg = String.Format(
                    "Call to class with affinity to thread {0} detected from thread {1}.",
                    m_threadId,
                    Thread.CurrentThread.ManagedThreadId);
                throw new InvalidOperationException(msg);
            }
        }
    }
    

    Blog post on the subject:

    • http://blogs.msdn.com/jaredpar/archive/2008/02/22/thread-affinity.aspx
    0 讨论(0)
提交回复
热议问题