Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>SHOOTING for the bounty!</p> <p>Okay, some classes/frameworks of classes in .NET have methods that are apartment bound, but BY DESIGN ONLY. That means you have to SPECIFICALLY CODE to do this. Its not set by default. Coding for this is kinda kludgy. You have to get the thread ID you want to stick with and check it all the time. I don't think there are any facilities in the framework that makes this easy, other than those for UI components tracking the UI thread. That support framework is probably buried deep within the UI stack; I've never seen it in any MSDN docs.</p> <p>What IS more common is setting the thread apartment. Lots of parts of the entire framework are restricted to STA threads by design (<a href="http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx" rel="nofollow noreferrer">STAThreadAttribute</a>). This is usually because they, deep down in their core, touch COM objects which often require that they are only used in STA threads. For example, the main thread in winforms apps is marked with the STAThreadAttribute, so that every UI component can only be touched within the same thread they are created, the UI thread. Interestingly, the XamlReader in WPF is aware of the current thread apartment and won't even deserialize UI components unless the thread its running in is an STA thread.</p> <p>"Does a standard POCO have thread affinity or care if its in a STA or MTA thread?" The answer is no, unless you code it to be so or mark its methods with the STAThreadAttribute <em>or if the object is instantiated in a call stack that, somewhere in its hierarchy, has a method marked with the STAThreadAttribute</em>.</p> <p>"Does an ADO.NET object have thread affinity, and is it apartment aware?" </p> <p>Well, a DbConnection extends from Component, which extends MarshalByRefObject. Component, MBRO, DbConnection and its descendents (i.e., SqlConnection) contain no methods that are marked with the STAThreadAttribute. A quick check of their major dependencies (such as DbTransaction) doesn't find that any of THOSE classes' methods are marked as STA only as well. Therefore they are not apartment aware.</p> <p>A quick browse with Reflector doesn't find any obvious thread-id watching. DbConnection does depend on Transaction, which seems like the most likely thread-fondler of the bunch.</p> <p>I busted out Reflector and checked out a few of these classes.<br> DbConnection - Doesn't care about the current thread's ID<br> SqlConnection - Does some thread tracking when debugging<br> SqlTransaction - Has a function called "ZombieCheck", but no thread watching<br> DbTransaction - Nothing here.</p> <p>So I think its safe to say that ADO.NET objects do NOT have thread affinity. I didn't even see them use <a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.beginthreadaffinity.aspx" rel="nofollow noreferrer">Thread.Begin/EndThreadAffinity</a>. </p> <hr> <p><strong>EDIT</strong></p> <p>As pointed out in the comments by Jeremy, I kept talking about the CLASSES being marked with the attribute rather than the CLASSES' METHODS. HUUUGE mistake. I screwed up bigtime by giving the impression that I only looked at the class definitions rather than the entire class.</p> <p>I've edited this to clarify, and let me say it here to be absolutely clear: No class methods in System.Data are marked with the STAThreadAttribute. You can check this for yourself with the following hacky code:</p> <pre><code>SqlConnection sc = new SqlConnection(); var data = AppDomain.CurrentDomain.GetAssemblies() .Where(x =&gt; x.FullName.StartsWith("System.Data,")).First(); var dtypes = data.GetTypes(); var results = new List&lt;string&gt;(); foreach (var type in dtypes) foreach (var method in type.GetMethods()) foreach (var attr in method.GetCustomAttributes(true).OfType&lt;System.Attribute&gt;()) { results.Add(string.Format("{0} {1} {2}", type.Name, method.Name, attr.GetType().Name)); if (attr.GetType() == typeof(STAThreadAttribute)) throw new Exception("SHIII"); } </code></pre> <p>Also, UI classes in winforms also don't use the STAThreadAttribute; its the application where this attribute is used (as, again, Jeremy pointed out). </p> <p>There is a special case where I've run into a class being apartment aware. The XamlReader, which deserializes xaml and creates WPF UI classes, will throw an exception when its Load method is called on a MTA thread. Its not even in the docs, which is annoying... So, again, classes aren't apartment aware by default; you have to code it that way or you have to make their instances aware by newing them up in a method chain containing a method marked by the STAThreadAttribute. Whew. This stuff is harder to explain than understand...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload