Ich bin neu in COM und versuche, den Unterschied zwischen STA und MTA zu verstehen. Ich habe versucht, ein Beispiel zu erstellen, das zeigen würde, dass COM Aufrufe von in STA erstellten Objekten verwalten kann, die nicht Thread-sicher sind.Kann COM-Objekt, das aus STAThread von anderen STA-Threads erstellt wird, nicht aufrufen
MyCalcServer
Klasse hier wird mit ATL Simple Object erstellt. Die Einstellungen sind die gleichen wie in this article:
- Threading Modell: Wohnung
- Aggregation: Kein
- Schnittstelle: Benutzerdefinierte
MyCalcServer
COM-Objekt verwendet wird, in ein anderes C# -Projekt, das ist:
class Program
{
[STAThread]
static void Main(string[] args)
{
MyCOMLib.MyCalcServer instance = new MyCOMLib.MyCalcServer();
string output1;
instance.ChangeValue("Gant", out output1);
Console.WriteLine(output1);
Thread t1 = new Thread(() =>
{
while (true)
{
string output;
instance.ChangeValue("Gant", out output);
Console.WriteLine(output);
}
});
t1.SetApartmentState(ApartmentState.STA);
t1.Start();
// :
// also has t2 and t3 here with similar code
// :
t1.Join(); t2.Join(); t3.Join();
}
}
Dies führt jedoch immer zu InvalidCastException
(E_NOINTERFACE) innerhalb des Codes von t1 ausgelöst. Ich habe auch versucht, ApartmentState zu MTA ohne Erfolg zu ändern.
Unable to cast COM object of type 'MyCOMLib.MyCalcServerClass' to interface type 'MyCOMLib.IMyCalcServer'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B005DB8C-7B21-4898-9DEC-CBEBE175BB21}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
Könnte jemand bitte erklären, was ich hier falsch mache?
Vielleicht denkt das JIT, dass Sie nicht "Instanz" verwenden und es früh freigeben. versuchen Sie, Marshal.ReleaseComObject (Instanz) nach den Joins zu setzen. – adrianm
@adrianm Immer noch nicht funktioniert, aber danke dafür – Gant
Versuchen Sie, die erste Zeile in MyCOMLib.IMyCalcServer zu ändern instance = new MyCOMLib.MyCalcServer(); Ich denke, nur Schnittstellen (keine Klassen) können zwischen Threads gemarshallt werden. – adrianm