Asynchronous support is not available for IDispatch - com

Microsoft's documentation states that Asynchronous support is not available for IDispatch or for interfaces that inherit IDispatch ...but I want to do exactly that (to call Excel asynchronously from C++ as part of pywin32 if that's relevant). Where does this limitation come from? Are there any workarounds that don't involve a pool of threads making synchronous calls?

Related

Can `SendChannel.offer`, `CompletableDeferred.complete`, and similar be called outside coroutines?

CompletableDeferred documentation says
All functions on this interface and on all interfaces derived from it are thread-safe and can be safely invoked from concurrent coroutines without external synchronization.
Is it safe to call these functions outside any coroutine?
For SendChannel<E>, offer and close are not suspend and so they can be called outside coroutines syntactically, but is it actually safe to do so?
If a coroutine is needed, what is the cheapest way to start one: launch(Unconfined)?
It is safe to call offer and close from anywhere. That is what documentation means to say with "are thread-safe" phrase.
One of the reasons these methods are included into channel APIs is to enable integration of coroutines with the regular non-coroutine world that is based on various callbacks and event handlers. You can see the actual example of such integration in this guide on UI programming with coroutines.

Windows Forms Project with Threading

I have read a LOT of material about Windows Form projects not supporting MTA. I get it. However, I also have read about Background worker, async/await and BeginInvoke use with such solutions. This and this are just a couple of examples. Here's one that even uses MSMQ. Some of the examples I have reviewed go way back to VB6 days.
I need to augment a Windows Form project with code to interact with a vendor service via API calls that could benefit from async capability. This being 2014, what is the best way to approach this? I use VB NET and have VS 2010 for my development.
Ideally, I would like to create a class library with the logic to interact with the vendor and just return the results to my Windows Form project. Can that be done?
The fact that MTA is not supported doesn't mean that you can't use multiple threads. The MTA model is just one way to use multiple threads, but because it's difficult to implement objects for that model, Windows Form uses the STA model instead.
The important effect of this is just that it means that the main thread in the application takes care of everything that has to do with the user interface. You can start as many threads as you like/need, but whenever anything from those threads needs to be displayed in the user interface, they have to use the Invoke method to let that update be done in the main thread.
There are already asynchronous method in the framework, for example the BeginRead and BeginWrite methods in the System.IO.FileStream class. You can have a look at those for some hints on how asynchronous methods are used in the framework.
If the API is synchronous, you would make asynchronous methods by simply starting a new thread that does the API call and then executes a callback method when it is done. As it's that thread that is waiting for the response, the call doesn't occupy the main thread.

Avoid COM marshalling

I'm a little confused about com threading models.
I have an inproc server and I want to create an interface accesible from any thread regardless of the threading-model and/or flags used in CoInitializeEx.
When passing interfaces from one thread to another I use CoMarshalInterface/CoUnmarshalInterface without problems but I want to know if exists any way to avoid that and directly pass the interface pointer.
I tried making the interface use neutral apartment but still have to call CoMarshalInterface/CoUnmarshalInterface to avoid problems.
Regards,
Mauro.
COM objects reside in one apartment only. Accessing a COM object via an interface pointer across apartment boundaries is never a good idea unless you're applicable scenario can utilize a free threaded marshaling aggregate. A free-threaded marshaller, essentially says that all clients of this interface, regardless of apartment and thread, are in the same process and will rely on the object itself to maintain synchronization and thread safety. The object itself must aggregate the free-threaded marshaller interface, so hopefully you're the author of it as well as the client code.
More information on free-threaded marshaling can be found at msdn.com, but one of their articles covering the object I tend to reuse again and again is this one.
I hope it helps you out.

Can a shared method be multithreaded?

As the question states, can a shared method of an object be multithreaded? I don't quite having threading down in my skillset, otherwise I would test myself. On the other hand, I am involved in designing class that could be part of a multithreaded application in VB.Net.
If you mean "is it safe for a shared method to be called from multiple threads at once" - the answer is "it depends". A method itself isn't multi-threaded or single-threaded; threads and methods are very separate things.
If your shared method is called from multiple threads, then unless there's any synchronization to say otherwise, it will be executed concurrently on those threads. That can definitely cause a problem if your method uses shared state without appropriate safeguards. However, if the method either takes care when accessing shared resources (e.g. using locks) or it doesn't access any state which is shared between threads, that's fine.
Yes, it can. Any method can become a thread.
Yes, shared methods can be executed simultaneously by multiple threads. In fact, they often are. You do not have as much control over which threads are executing shared methods as compared to instance methods. Consider an ASP.NET application for example. Different page requests may come in on different threads. If you call a shared method in your web application then there is a high probability that it is getting executed by multiple threads.
This is an incredibly important point when designing an API. All self respecting API authors go to extremes to make sure all shared/static methods are thread-safe. Afterall, it would be ridiculously onerous to make a caller of your API synchronize access to every single shared/static method you provide. Take a look at the documentation Microsoft provides for almost all classes in the BCL.
Any public static (Shared in Visual Basic) members of this type are
thread safe. Any instance members are not guaranteed to be thread
safe.
I have yet to run across a static method provided by Microsoft that was not thread-safe.1 And that is good because it makes life easier for you and I.
1If you know of one let me know.

How to access COM objects from different apartment models?

I have a multi-threaded C++Builder GUI app, which communicates with a third-party app via COM.
I need to call methods of the COM object from several threads, and I'm protecting access with a mutex. Apparently, the main GUI thread must use STA model, but my worker threads need to use MTA. The COM object is constructed in an MTA thread.
Everything works fine except access to the COM object from the GUI thread, due to the MTA/STA mismatch.
I've read a bit about marshalling, but haven't tried to implement it, because the examples I've seen seem to require different access semantics depending the the current apartment model, and I really would like to have code that (from a programmer's POV) doesn't care about the current apartment model.
So, is there an idiomatic way to write COM code that operates on the 'same' object, but can be called from both STA and MTA threads?
Put the COM object interface into the Global Interface Table and let the GIT handle the marshalling for you. When any thread requests the COM interface, the GIT checks the calling apartment and will provide a direct pointer or a suitable proxy accordingly. Your code won't know the difference (or care), just use the returned interface normally as needed.
This is documented on MSDN:
Accessing Interfaces Across Apartments