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.
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.
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.
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.
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
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With