Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I detect multi-threaded use?

Is it sufficient to compare the ManagedThreadId at the time an object is created and at the time a method is called to verify that it isn't being used in a multithreading scenario?

public class SingleThreadSafe
{
    private readonly int threadId;
    public SingleThreadSafe()
    {
        threadId = Thread.CurrentThread.ManagedThreadId;
    }

    public void DoSomethingUsefulButNotThreadSafe()
    {
        if(threadId!=Thread.CurrentThread.ManagedThreadId)
        {
            throw new InvalidOperationException(
                "This object is being accessed by a thread different than the one that created it. " +
                " But no effort has been made to make this object thread safe.");
        }
        //Do something useful, like use a previously established DbConnection
    }
}

My intuition is often wrong about threading, so I wanted to check to see if there are edge cases I should be keeping in mind.

like image 892
MatthewMartin Avatar asked Jun 04 '14 20:06

MatthewMartin


People also ask

How can you tell if an application is multi threaded?

For Windows you can run the program and then open task manager by pressing ctrl+shift+esc keys. Look for processes with a number in parentheses after the name: That is the number of tasks the program currently has active. Single-threaded programs won't have multiple tasks.

Where are multiple threads used?

What Is Multithreading Used For? The main reason for incorporating threads into an application is to improve its performance. Performance can be expressed in multiple ways: A web server will utilize multiple threads to simultaneous process requests for data at the same time.

What is multithreading give me an example of where it is used and what are the resources shared between multiple threads?

Multithreading is the ability of a program or an operating system to enable more than one user at a time without requiring multiple copies of the program running on the computer. Multithreading can also handle multiple requests from the same user.


2 Answers

No it is not sufficient !

A managed thread id can be reused by the CLR, so if(threadId!=Thread.CurrentThread.ManagedThreadId) can return false even is the calling thread is different from the one used to construct the object.

What you are trying to achieve is possible through references comparisons:

if (!object.ReferenceEquals(Thread.CurrentThread, ThreadThatCreatedThis))
// ...

EDIT :

MSDN says however that :

The value of the ManagedThreadId property does not vary over time, even if unmanaged code that hosts the common language runtime implements the thread as a fiber.

http://msdn.microsoft.com/en-us/library/system.threading.thread.managedthreadid%28v=vs.110%29.aspx

like image 120
quantdev Avatar answered Oct 14 '22 22:10

quantdev


That's basically what Windows Forms does. Here's a snippet from Control.InvokeRequired (quoted from the reference source):

public bool InvokeRequired {
    get {
        using (new MultithreadSafeCallScope())
        {
            ...
            int hwndThread = SafeNativeMethods.GetWindowThreadProcessId(hwnd, out pid);
            int currentThread = SafeNativeMethods.GetCurrentThreadId();
            return(hwndThread != currentThread);
        }
    }
}

If comparing thread IDs is good enough for Windows Forms, I suppose it'd be good enough for me...

like image 21
Heinzi Avatar answered Oct 14 '22 23:10

Heinzi