问题
My previous question (SelectedIndex is unchanging in tabcontrol - Dispatcher issue) didn't get very far, and I suspect I was on the wrong track to begin with.
There are 3 givens in my program:
- I have a main window which is WPF.
- I connect to a separate application (a different process) which implements a COM server which can be called on at various times to perform time-consuming calculations, the results of which I will display in my window.
- I do not want the main window to freeze while waiting for these calculations to conclude. In fact, the operator should be free to continue using the program, though certain controls may be disabled pending conclusion of the asynchronous operation.
It seems to me that to achieve the above requirements that I need to have a separate thread dedictated to handling COM requests and that thread must be STA. Somehow I invoke this thread to do stuff, and somehow this thread invokes the GUI thread to update stuff. It's not clear to me technically how to make this happen.
Two questions: How do I implement these calls between threads? What's a clean architecture for this?
回答1:
Depending on your COM server you may use either an MTA or an STA threading model. The STA, Single Threaded Apartment is the simplest to use and the one I would recommend to begin with unless you are certain your COM supports MTA and you need to use MTA.
A safe way of calling long running COM objects is the following standard pattern: - From the UI thread start a new thread where your COM object will be called from. You can use a Task or a thread. Change the Thread Apartment to STA: System.Threading.Thread.CurrentThread.ApartmentState = ApartmentState.STA
Then from that thread you can instantiate and run your COM object as normal. When it has finished or when you get events from it that need to be passed on the main UI thread you raise an event from your code passing in the data (do not pass back the COM object, you need to decouple the data from it since it belongs to another thread) which your UI thread will intercept.
On your UI thread when you get back the event, you will need to use InvokeRequired / BeginInvoke if you use WinForm. I am not sure about WPF but I would expect you would need to synchronize the callback with the UI thread too.
来源:https://stackoverflow.com/questions/27444483/how-to-have-an-async-connection-to-com-with-a-wpf-interface