There's a COM library I need to use that CANT be changed.
The Apartment State is STA and can't be switched to MTA without refactoring.
It's got two methods
Method One is a short operation
Method Two is a long running operation
I'd like to be able to make calls to Method One even if Method Two is in progress.
One approach I've considered is copying and altering the COM component's actual binary and registering it as a totally different COM component, then using an instance of this alias'd library to do the calls to Method Two so that the main instance is only responsible for calls to Method One.
I've tried just opening up the DLL in a hex editor and replacing the ProgID and ClsId, but that doesn't seem to be working. The registry entries I'm aware of look right, but when I add a reference in visual studio in order to generate my interop assembly, the generated library still has the old ClsId and calls to Method One still block until Method Two completes.
Any ideas on how I can make this work?
Is this approach totally misguided or am I on the right track?
Creating two STA threads to handle invocations to the component definitely allowed me to make concurrent calls.
The solution here actually was way simpler than the craziness I was talking about initially. I had considered this solution before, but thought I'd tried it and it hadn't worked. Something must have been wrong with my previous implementation.
Specifically, I've got two STA threads in which I'm instantiating my COM component, and then I'm passing invocation requests to these threads via a blocking collection. The calls specified in the request objects are made and the request objects are provided with responses which signals the calling thread that the call is complete.
#IgorTandetnik pointed me in this direction.
Related
I have a component registered in Castle Windsor as a singleton. This object is being used in many other places within my application which is multithreaded.
Is it possible that the two objects will invoke the same method from that singleton at the same time or 'calling it' will be blocked until the previous object will get result?
Thanks
You can call a Singleton object method from different threads at the same time and they would not be blocked if there is no locking/ synchronization code. The threads would not wait for others to process the result and would execute the method as they would execute methods on separate objects.
This is due to the fact that each thread has a separate stack and have different sets of local variables. The rest of the method just describes the process as to what needs to be done with the data which is held the variables/fields.
What you might want to take care of is if the methods on the Singleton object access any static methods or fields/variables. In that case you might need to work on synchronization part of it. You would need to ensure multi-threaded access to shared resources for the execution of the method to be reliable.
To be able to synchronize, you might need to use lock statement or other forms of thread synchronization techniques.
You might want to refer to this article from Wikipedia which provides information on C# thread local storage as well.
You can call the same method or different methods on one object simultaneously from different threads. In the specific methods you'll need to know when sensitive variables are being accessed (mostly when member-variables are changing their values) and will need to implement locking on your own, in order to solve lost updates and other anomalies.
You can lock a part of a code with the lock-statement and here an article on how Thread-Synchronization works in .Net.
The normal version of Singleton may not be thread safe, you could see different implementation of thread safe singleton here.
http://tutorials.csharp-online.net/Singleton_design_pattern:_Thread-safe_Singleton
I need to organise some lock when several threads get access to common resource at next code architecture:
There is one dll what has methods (marked with some attribute) which are called by reflection by external program. All this methods are called simultaneously by several threads from that external program.
Inside this methods we have references to other methods what are located in another dll. Inside that another we have methods from other dll.
External run program - (reflection) > dll -> dll -> dll
Everything was ok till the moment when all threads started go use the same resource (access to email box) at the last dll in a chain.
One try to delete message but another has already deleted it etc. In fact I do not care about it and can put try/catch if message does not exists but I do not want to use this solution.
I'm thinking about add some lock to read and delete operation and make this delete async way (I do not care about result and do not need to wait till it will be finished - just cleaning old messages) and use some code like below
lock(someObject)
{
//Access to email and delete old messages
}
But someObject has to be declared at the top level of that architecture (External run program) and this parameter has to be passed thought all chain. A lot of work and I do not want to do it.
Also I can put this lock at top program what run dll methods but a lot of changes need to be done too because I'll loose a lot of time because I ned to lock small part only but not all.
Any other suggestions?
An architectural suggestion would be creating a queue of operation accessing the mail resource, to avoid locking. This will loose a feedback for the caller, but it can be done asynchronously if needed. May be just the deleting phase has to be done enqueued, this depend on the exact job you are trying to do. Of course such a queue must be threaed safe, and depending on the level of reliability you want, can be a persistent queue ( like MSMQ )
I do think that the try catch solution you suggested is fine as long as there is no dependency with regard to order between threads (one thread creating a message, another thread adding an attachment to it). In that case the Queue as mentioned by Felice Pollano might be a good solution.
In the end, whether you lock or not, you'll need to handle conflicts. If these conflicts are predictable you could use locking otherwise try catch might be just fine.
Although there are many questions about COM and STA/MTA (e.g. here), most of them talk about applications which have a UI. I, however, have the following setup:
A console application, which is by default Multi-Threaded Apartment (Main() explicitly has the [MTAThread] attribute).
The main thread spawns some worker threads.
The main thread instantiates a single-threaded COM object.
The main thread calls Console.ReadLine() until the user hits 'q', after which the application terminates.
A few questions:
Numerous places mentions the need of a message pump for COM objects. Do I need to manually create a message-pump for the main thread, or will the CLR create it for me on a new STA thread, as this question suggests?
Just to make sure - assuming the CLR automagically creates the necessary plumbing, can I then use the COM object from any worker thread without the need of explicit synchronization?
Which of the following is better in terms of performance:
Let the CLR take care of the marshaling to and from the COM object.
Explicitly instantiate the object on a separate STA thread, and have other thread communicate with it via e.g. a ConcurrentQueue.
This is done automagically by COM. Since your COM object is single-threaded, COM requires a suitable home for the object to ensures it is used in a thread-safe way. Since your main thread is not friendly enough to provide such guarantees, COM automatically creates another thread and creates the object on that thread. This thread also automatically pumps, nothing you have to do to help. You can see it being created in the debugger. Enable unmanaged debugging and look in the Debug + Windows + Threads window. You'll see the thread getting added when you step over the new call.
Nice and easy, but it does have a few consequences. First off, the COM component needs to provide a proxy/stub implementation. Helper code that knows how to serialize the arguments of a method call so the real method call can be made on another thread. That's usually provided, but not always. You'll get a hard to diagnose E_NOINTERFACE exception if it is missing. Sometimes TYPE_E_LIBNOTREGISTERED, a common install problem.
And most significantly, every call on the COM component will be marshaled. That's slow, a marshaled call is usually around 10,000x slower than a direct call on a method that itself takes very little time. Like a property getter call. That can really bog your program down of course.
An STA thread avoids this and is therefore the recommended way to use a single-threaded component. And yes, it is a requirement for an STA thread to pump a message loop. Application.Run() in a .NET program. It is the message loop that marshals calls from one thread to another in COM. Do note that it doesn't necessarily mean that you must have a message loop. If no call ever needs to marshaled, or in other words, if you make all the calls on the component from the same thread, then the message loop isn't needed. That's typically easy to guarantee, particularly in a console mode app. Not if you create threads yourself of course.
One more nasty detail: a single-threaded COM component sometimes assumes it is created on a thread that pumps. And will use PostMessage() itself, typically when it uses worker threads internally and needs to raise events on the STA thread. That will of course not work correctly anymore when you don't pump. You normally diagnose this by noticing that events are not being raised. The common example of such a component is WebBrowser. Which heavily uses threads internally but raises events on the thread on which it was created. You'll never get the DocumentCompleted event if you don't pump.
So putting [STAThread] on your Main() method might be enough to get happy fast code, even without a call to Application.Run(). Just keep the consequences in mind, seeing a method call deadlock or an event not getting raised is the tell-tale sign that pumping is required.
Yes, it is possible to create a STA COM object from an MTA thread.
In this case, COM (not CLR) will create an implicit STA apartment (a separate COM-owned thread) or re-use the existing one, created ealier. The COM object will be instantiated there, then a thread-safe proxy object (COM marshalling wrapper) will be created for it and returned to the MTA thread. All calls to the object made on the MTA thread will be marshalled by COM to that implicit STA apartment.
This scenario is usually undesirable. It has a lot of shortcomings and may simply not work as expected, if COM is unable to marshal some interfaces of the object. Check this question for more details. Besides, the message pump loop, run by the implicit STA apartment, pumps only a limited number of COM-specific messages. That may also affect the functionality of the COM.
You may try it and it may work well for you. Or, you may run into some unpleasant issues like deadlocks, quite difficult to diagnose.
Here is a closely related question I just recently answered:
StaTaskScheduler and STA thread message pumping
I'd personally prefer to manually control the logic of the inter-thread calls and thread affinity, with something like ThreadAffinityTaskScheduler proposed in my answer.
You may also want to read this: INFO: Descriptions and Workings of OLE Threading Models, highly recommended.
Do I need to manually create a message-pump for the main thread,
No. It is in the MTA therefore no message pump is needed.
or will the CLR create it for me on a new STA thread
If COM creates the thread (because there is no STA in the process) then it also creates the message pump (and a hidden window: can be seen with the SPY++ and similar debugging tools).
COM object from any worker thread without the need of explicit synchronization
Depends.
If the reference to the single threaded object (STO) was created in the MTA then COM will supply the appropriate proxy. This proxy is good for all threads in the MTA.
In any other case the reference will need to be marshalled to ensure it has the correct proxy.
is better in terms of performance
The only answer to this is to test both and compare.
(Remember if you create the thread for the STA and then instantiate the object locally you need to do the message pumping. It is not clear to me that there is any CLR level lightweight message pump—including WinForms just for this certainly isn't.)
NB. The only in depth explanatory coverage of COM and the CLR is .NET and COM: The Complete Interoperability Guide by Adam Nathan (Sams, January 2002). But it is based on .NET 1.1 and now out of print (but there is a Kindle edition and is available via Safari Books Online). Even this book doesn't describe directly what you are trying to do. I would suggest some prototyping.
Extension to Release COM Object in C#
I noticed that saving the MailItem and releasing is a time consuming task. So, it is safe to do the following ? (pseudo-code below)
Thread 1 (main thread)
- Open 10 (different .msg files) - MailItems [List<MailItem> items]
- user works on them and want to save and close all of them with one click.
- On_save_All_click (runs on main thread)
- Do
- toBeClearedList.addAll(items);
- items.clear() [so that main thread cannot access those items]
- BG_Thread.ExecuteAsyn(toBeClearedList);
- End
Thread 2 (background thread) (input - List<MailItems>)
- foreach(MailItem item in input)
item.save();
System.Runtime.InteropServices.Marshal.ReleaseComObject(item)
- done
I wrote couple of tests and looks like its working; Just want to know if its safe to do so ? "Releasing COM objects in different thread than the one in which it was created"
Thanks
Karephul
When using COM from unmanaged code (C/C++), the rules are pretty strict: you can only call methods on an interface from the same apartment that you acquired the object on. So if you obtain an interface pointer on an STA thread, then only that thread is allowed to call any of the methods. If you obtain an interface pointer on an MTA thread, then only other threads in the same MTA can use that pointer. Any other use that crosses apartments requires that the interface pointer is marshaled to the other apartment.
However, that's unamanged world. .Net adds a whole layer on top of COM which buries a lot of these low-level details, and for the most part, once you get your hands on an interface, you can pass that interface around between threads as much as you please without having to worry about the old threading rules. What's happening here is that it are actually passing around references to an object called a "Runtime Callable Wrapper" (RCW), and it is managing the underlying COM interface, and controlling access to it accordingly. (It takes on the burden of upholding the COM apartment rules so that you don't have to, and that's why it can appear that the old COM threading rules don't apply in .Net: they do, they're just hidden from you.)
So you can safely call Release or other methods from another thread: but be aware that if the original thread was STA, then calling those methods will cause the underlying RCW to marshal the call back to the original owning thread so that it still upholds the underling COM rules. So using a separate thread may not actually get you any performance in the end!
Some articles worth reading that fill in some of the details here:
The mapping between interface pointers and runtime callable wrappers (RCWs) - good overview of some of the details of how RCW's work, but it doesn't say much about threading.
Improving Interop Performance - Marshal.ReleaseComObject - some good notes on when to use or not use ReleaseComObject, and how it works with the RCWs.
cbrumme's WebLog - Apartments and Pumping in the CLR - more internals than you're likely to want to know; this is a couple of CLR releases out of date, but still gives a good insight into how .Net covers over many of the underlying COM issues.
If I remember my COM properly (I always hated that technology, way too complicated), if the COM object is single-threaded (that is, belongs in a single-threaded-apartment), releasing it from another thread isn't going to do you any good - it's just going to execute the actual release code in your main thread.
You are going to see a little difference between your code, and releasing the objects from the main thread in one loop. If you release the objects in one loop, your UI is going to be unresponsive until you release all messages. By using a secondary thread, your UI thread will release one message, then handle other events, then release another, and so on. You can get the same effect by sending yourself a message (or using a Dispatcher if you have a WPF application), and avoid having another thread.
I had an idea for solving the problem of enumerating managed threads in .Net and for tracking thread ancestry (which thread created which other thread).
If it were possible to tag a Thread object with an object of the programmer's making that is automatically copied to children threads when they are created, it might be possible to use that tag to track when new threads are created, who created them, etc. The inspiration came from unix, where, when a process is forked, it inherits open file handles, etc. If there were some piece of data that is 1) thread-local or tied to a Thread object and 2) is automatically copied to new threads and 3) is modifiable, that would be a good start.
I'm guessing that we'll have to use reflection to access members of some of the Thread object that starts the chain because most of what i see in the thread that might be useful is otherwise locked up, but it's an start. I'm not sure how wise this approach is though.
Edit:
I think I'll explain my use case better because I don't think anybody understands.
I know about tracking threads explicitly, which I've done widely in code i own before. That's not the problem.
Basically, I'm trying to implement a 'thread-group-context', much in the same way that .Net has an appdomain-context, a remoting context [1] and an assembly-thread combination-local context [2].
For a given group of threads that were spawned from a common thread, I want to associate information with that grouping. While I understand that .Net doesn't have this concept (else I would have no problem!), it doesn't change the fact that every managed thread in .Net was created by one and only one other managed thread, and thus, can be drawn in a tree structure.
The problem I am trying to solve is thus: I have an API, that has an context object. This API calls into a large external library of code that does real work, and does so starting from a thread of its creation. That external does not explicitly get a copy of the API context object, however it would need one in order to make calls on the API. Since it does not have a reference to the API context object, it cannot make these calls. As things stand today, the external library does need to make calls, and to do so it looks up the current context object in a single static field, meaning that there can only be one instance of my API per AppDomain. I wish to fix this.
This external library is partly out of my control, and the interface between my API and the external library does not explicitly pass the context object. Up until now, when the external library needed to make calls into the API, it would look at a static field in my API to get a reference to the context object.
The problem is then that a final executable can only have one instance of my API session per AppDomain, because we're using static fields to pass the context object to the external library (workhorse) code.
One option is to make a GetContextObject() method in my API. When the API spawns the thread to run the external library code, it would remember that thread in a shared static dictionary. When the external library code calls GetContextObject(), it would look up what thread it is running on and return the proper context object for that thread.
If the external library code never created its own threads, then I'd have no problem, I'd always have a 100% correct mapping of thread to context. However, the external library does make its own threads, and does so without my API being aware. When the API receives a call from those threads, it won't know what context object to give up, and has to guess - if there's only one context object registered, it uses that, otherwise, it throws an exception saying it can't tell you.
If I could have data tagged to thread objects that is inherited by threads created by that parent thread, then I could implement this tracking system.
Also, the external library does not use the thread pool.
Basically, my options are thus:
1) Redesign the interface between my API and the external library to pass in the context object, and redesign the external library to correctly pass around this context object. Involves trundling through ~1 million LOC.
1a) Forbid the external library from directly using the Thread object, and instead require them to use my own MyApiThread object that, when created, adds itself to my custom tracking mechanism. Requires changing less code in the external library than option #1, but still involves a lot of rework.
2) Force the consumer of my API to start each API session in a new AppDomain so that I can store my context object in a static field (this is the 'solution' today). AppDomains involve a lot of overhead and I do not wish to force this upon my users.
3) Find a way to track thread ancestry to be able to return the correct context object to the code calling from the external library based on the calling thread. This is the subject of this post.
To those saying that Windows does not have a concept of child-parent threading, you are off base - that is irrelevant. DotNet is not a Windows-only system, and its very design was to isolate it from the machine and OS it is running on, which is why .Net exists for Linux, Solaris, FreeBSD in the form of Mono. Furthermore, Java does have the very concept of thread ancestry that I need, and Java is implemented on Windows, thus this is a very possible and reasonable concept. While I realize that the .Net api has a certain Microsoft-specific bend to it, realize that, largely, .Net and Windows are independent.
In fact, I'll make my comment an answer and point you at Jeffrey Richter.
The CallContext class gives you the ability to store data for a "logical execution path", which can cross threads and AppDomains.
Just adding more info for shambulator answer.
CallContext.GetLogicalData and CallContext.SetLogicalData do the trick