与单例对象的交互

来源 目录

与单例对象的交互

关于单例对象

单例是只支持一个对象实例的对象。在 ArcObjects 中,单例对象需要通过 Activator 类进行实例化,并且需要通过 ComReleaser 类显式释放。 此外,一个线程中的所有 ArcObjects 引用应该只与同一线程中的对象通信。 因此,在 ArcGIS 中,单例对象是每个线程的单例,而不是每个进程的单例,如 Writing multithreaded ArcObjects code

单例和 System.__COMObject

在主题 【在.net 中对 ArcObjects 的应用 】中,“RCW 类和 System.__COMObject”部分显示,当您使用 new 关键字实例化 COM 对象时,会创建一个强类型 RCW,而如果该对象是已存在的,则 RCW 的类型是一般性的System._ComObject。

然而有的时候,当您使用 new 关键字来实例化 COM 对象时,您却会获得一个对已有对象的引用。当尝试实例化一个已实例化的单例类时,会发生这种情况。

在.NET Framework 中,已包装在一般性的 System._ComObject RCW 中的 COM 对象,无法再被包装到强类型 RCW 中去。如果您的代码遇到这种情况,您可能会收到一个错误,例如:

无法将类型为“System.__ComObject”的对象强制转换为类型 <Typename>
Unable to cast object of type System._ComObject to type <Typename>

请参见以下代码示例:

[C#]

ESRI.ArcGIS.Display.IStyleGallery sg=new ESRI.ArcGIS.Framework.StyleGalleryClass();

[VB.NET]

Dim sg As ESRI.ArcGIS.Display.IStyleGallery=New ESRI.ArcGIS.Framework.StyleGalleryClass

译者自己提供示例:

public static ISpatialReference CreateSpatialReference(int wkid)
{
	if (wkid == 0)
	{
		return null;
	}

	ISpatialReference spr = null;
	ISpatialReferenceFactory3 sprFactory = null;
	if (IsGeographic(wkid))
	{
        //错误:
        //在多线程运行环境中,可能招出异常:
        //  System.InvalidCastException: 无法将类型为“System.__ComObject”的对象强制转换为
        //  类型“ESRI.ArcGIS.Geometry.SpatialReferenceEnvironmentClass”。
        // --------
        //因为这个 SpatialReferenceEnvironmentClass 类实例,需要做到每线程单例;
        //  若用 new 语句,则之前已经实例化的、已经包装在 “System.__ComObject”中的这个类实例,
        //    会被 .net 运行时尝试包装到 强类型 RCW 中,从而报错
		sprFactory = new SpatialReferenceEnvironmentClass();
		spr = sprFactory.CreateGeographicCoordinateSystem(wkid);
	}
	else if (IsProjected(wkid))
	{
        //错误:同上
		sprFactory = new SpatialReferenceEnvironmentClass();
		spr = sprFactory.CreateProjectedCoordinateSystem(wkid);
	}
	AOUtil.Release(sprFactory);
	return spr;
}

public class AOUtil
{
	/// <summary>
	/// 释放AO非托管对象
	/// </summary>
	public static void Release<T>(T obj)
	{
		if (obj == null) return;
		int refsLeft;
		do
		{
			refsLeft = Marshal.ReleaseComObject(obj);
		}
		while (refsLeft > 0);
		obj = default;
	}
}

即使您使用接口名称来声明变量,而不是类名称来声明变量,也可能会发生前面的错误。如上面的示例所示。出现此问题的原因是,当您的代码实例化一个对象时,.NET 运行时首先尝试将对象包装在【强类型的类】的类型(即在 new 关键字之后声明的类型)中,然后再尝试转换为接口类型。 在向强类型 RCW 的强制转换的过程中失败,无法成功,因为 COM 对象先前已包装在一般性的 System._ComObject 包装器中。 这可能发生在您无法控制的情况下。 例如,第三方用 .NET 编写的其他 ArcObjects 工具可能会将对象包装在通用包装器中,从而导致您的代码失败。

解决方案是使用 Activator 类,如下所示,在您第一次获得对单例对象的引用时,将其安全地包装在强类型 RCW 中。 此外,在一般情况下,应该始终使用接口,而不是类的类型来,声明持有 RCW 的变量。

使用 Activator 类创建单例

如果使用 Activator 类的 CreateInstance 方法,而不是 new 关键字来实例化单例,则可以避免上一节中讨论的错误,因为 Activator 可以获得执行转换所需的元数据。

请参见以下代码示例:

[C#]

Type t=Type.GetTypeFromProgID("esriFramework.StyleGallery");
System.Object obj=Activator.CreateInstance(t);
IStyleGallery sg=obj as IStyleGallery;

[VB.NET]

Dim t As Type=Type.GetTypeFromProgID("esriFramework.StyleGallery")
Dim obj As System.Object=Activator.CreateInstance(t)
Dim pApp As ESRI.ArcGIS.Display.IStyleGallery=obj

译者示例的解决办法:

if (IsGeographic(wkid))
{
	Type t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
	object obj = Activator.CreateInstance(t);
	sprFactory = obj as ISpatialReferenceFactory3;
	spr = sprFactory.CreateGeographicCoordinateSystem(wkid);
}
else if (IsProjected(wkid))
{
	Type t = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
	object obj = Activator.CreateInstance(t);
	sprFactory = obj as ISpatialReferenceFactory3;
	spr = sprFactory.CreateProjectedCoordinateSystem(wkid);
}

实例化 AppRef 类

您可以使用前面的技术,来实例化 AppRef 类; 但是,AppRef 类只能在 ArcGIS 应用程序中创建(类型是一般性的 System._ComObject RCW)。

请参见以下代码示例:

[C#]

Type t=Type.GetTypeFromProgID("esriFramework.AppRef");
System.Object obj=Activator.CreateInstance(t);
ESRI.ArcGIS.Framework.IApplication pApp=obj as ESRI.ArcGIS.Framework.IApplication;

[VB.NET]

Dim t As Type=Type.GetTypeFromProgID("esriFramework.AppRef")
Dim obj As System.Object=Activator.CreateInstance(t)
Dim pApp As ESRI.ArcGIS.Framework.IApplication=obj

ArcObjects 中的单例对象

下表列出了 ArcGIS 中的单例对象。 带有星号 (*) 的类型是每个进程的单例(区别于每个线程的单例)。

Class Library ProgID GUID Location
AccessWorkspaceFactory DataSourcesGDB esriDataSourcesGDB.AccessWorkspaceFactory dd48c96a-d92a-11d1-aa81-00c04fa33a15 D, E, S
AMSWorkspaceFactory TrackingAnalyst esriTrackingAnalyst.AMSWorkspaceFactory a677ab59-2fb8-11d5-b7e2-00010265adc5 D, E, S
ArcInfoWorkspaceFactory DataSourcesFile esriDataSourcesFile.ArcInfoWorkspaceFactory 1d887452-d9f2-11d1-aa81-00c04fa33a15 D, E, S
CadWorkspaceFactory DataSourcesFile esriDataSourcesFile.CadWorkspaceFactory 9e2c27ce-62c6-11d2-9aed-00c04fa33299 D, E, S
ExcelWorkspaceFactory DataSourcesOleDB esriDataSourcesOleDB.ExcelWorkspaceFactory 30f6f271-852b-4ee8-bd2d-099f51d6b238 D, E, S
FileGDBWorkspaceFactory DataSourcesGDB esriDataSourcesGDB.FileGDBWorkspaceFactory 71fe75f0-ea0c-4406-873e-b7d53748ae7e D, E, S
IMSWorkspaceFactory GISClient esriGISClient.IMSWorkspaceFactory bac84d58-fa9d-11d3-9f48-00c04f79927c D, E, S
InMemoryWorkspaceFactory DataSourcesGDB esriDataSourcesGDB.InMemoryWorkspaceFactory 7f2bc55c-b902-43d0-a566-aa47ea9fda2c D, E, S
NetCDFWorkspaceFactory DataSourcesNetCDF esriDataSourcesNetCDF.NetCDFWorkspaceFactory df61a9e1-b8e2-498f-bde5-98de42e801f9 D, E, S
OLEDBWorkspaceFactory DataSourcesOleDB esriDataSourcesOleDB.OLEDBWorkspaceFactory 59158055-3171-11d2-aa94-00c04fa37849 D, E, S
PCCoverageWorkspaceFactory DataSourcesFile esriDataSourcesFile.PCCoverageWorkspaceFactory 6de812d2-9ab6-11d2-b0d7-0000f8780820 D, E, S
RasterWorkspaceFactory DataSourcesRaster esriDataSourcesRaster.RasterWorkspaceFactory 4c91d963-3390-11d2-8d25-0000f8780535 D, E, S
SchematicWorkspaceFactory Schematic esriSchematic.SchematicWorkspaceFactory e18fc71c-fda7-4c7b-a824-c024d7900b5d D, E, S
ScratchWorkspaceFactory DataSourcesGDB esriDataSourcesGDB.ScratchWorkspaceFactory 06dc8e4c-951c-11d2-ae75-080009ec732a D, E, S
SDCWorkspaceFactory DataSourcesFile esriDataSourcesFile.SDCWorkspaceFactory 34dae34f-dbe2-409c-8f85-ddbb46138011 D, E, S
SdeWorkspaceFactory DataSourcesGDB esriDataSourcesGDB.SdeWorkspaceFactory d9b4fa40-d6d9-11d1-aa81-00c04fa33a15 D, E, S
ShapefileWorkspaceFactory DataSourcesFile esriDataSourcesFile.ShapefileWorkspaceFactory a06adb96-d95c-11d1-aa81-00c04fa33a15 D, E, S
StreetMapWorkspaceFactory DataSourcesFile esriDataSourcesFile.StreetMapWorkspaceFactory ae2469e8-e110-4cd6-b3f4-a756cbf921ca D, E, S
TextFileWorkspaceFactory DataSourcesOleDB esriDataSourcesOleDB.TextFileWorkspaceFactory 72ce59ec-0be8-11d4-ae03-00c04fa33a15 D, E, S
TinWorkspaceFactory DataSourcesFile esriDataSourcesFile.TinWorkspaceFactory ad4e89d9-00a5-11d2-b1ca-00c04f8edeff D, E, S
ToolboxWorkspaceFactory Geoprocessing esriGeoprocessing.ToolboxWorkspaceFactory e9231b31-2a34-4729-8de2-12cf39674b1b D, E, S
VpfWorkspaceFactory DataSourcesFile esriDataSourcesFile.VpfWorkspaceFactory 397847f9-c865-11d3-9b56-00c04fa33299 D, E, S
WorkspaceFactory Geodatabase esriGeodatabase.WorkspaceFactory FBF5715D-A05D-11D4-A64C-0008C711C8C1 D, E, S
AGSServerConnectionFactory GISClient esriGISClient.AGSServerConnectionFactory 7932a86e-f371-4c64-ab84-9e83dda2581b D, E, S
WMSConnectionFactory GISClient esriGISClient.WMSConnectionFactory f7c34345-87ce-4ab5-9ca8-2012d7241075 D, E, S
GPGlobeFunctionFactory GlobeCore esriGlobeCore.GPGlobeFunctionFactory 9e8cedbd-fd6f-41d8-93a0-35207790ba08 D, E, S
GPServerFunctionFactory Geoprocessing esriGeoprocessing.GPServerFunctionFactory f8ac2c04-deec-43f4-86ef-246f91f12856 D, E, S
MemoryRelationshipClassFactory Geodatabase esriGeodatabase.MemoryRelationshipClassFactory 2fc5c57b-eb92-4a61-bbc5-434e388bf3b9 D, E, S
RelQueryTableFactory Geodatabase esriGeodatabase.RelQueryTableFactory 9b4e4d0c-753a-43bb-83fb-ba16f6652e1c D, E, S
ActionEnvironment * TrackingAnalyst esriTrackingAnalyst.ActionEnvironment 1e18428c-86eb-4678-a987-f8157feb77cf D, E, S
CommandsEnvironment Controls esriControls.CommandsEnvironment 46d9c72e-4dc2-4589-b809-a51fc4a57684 D, E, S
DddEnvironment 3DAnalystUI esri3DAnalystUI.DddEnvironment 94305472-592e-11d4-80ee-00c04fa0adf8 D
DddServerEnvironment Geodatabase esriGeodatabase.DddServerEnvironment 3b6c52a4-7231-4189-b341-c30e7fb58bcf D, E, S
DDDToolbarEnvironment 3DAnalystUI esri3DAnalystUI.DDDToolbarEnvironment 2d73b143-8f1c-11d4-a10f-00508bd60cb9 D
EngineNetworkAnalystEnvironment Controls esriControls.EngineNetworkAnalystEnvironment 7da28a78-4027-4cc8-a8c3-fd31c6f22e9e E
EnvironmentManager System esriSystem.EnvironmentManager 8a626d49-5f5e-47d9-9463-0b802e9c4167 D, E, S
GMxEffectsToolbarEnvironment ArcGlobe esriArcGlobe.GMxEffectsToolbarEnvironment 3eafa611-dc74-4c29-bab6-c401e7c76ac6 D
LabelEnvironment Carto esriCarto.LabelEnvironment 76765b96-ce78-11d2-9f36-00c04f6bc6a5 D, E, S
LayerEffectsEnvironment ArcMapUI esriArcMapUI.LayerEffectsEnvironment 377aba22-2019-11d3-9f97-00c04f6bc78e D
RasterAnalysisToolbarEnvironment SpatialAnalystUI esriSpatialAnalystUI.RasterAnalysisToolbarEnvironment 89daddfd-79ec-4f5e-8252-ae716a89ac15 D
RasterDefaultsEnv Carto esriCarto.RasterDefaultsEnv eb0d0573-c109-11d2-9f43-00c04f8ed21a D, E, S
SelectionEnvironment Carto esriCarto.SelectionEnvironment e3875b71-d9f5-11d1-add4-080009ec732a D, E, S
SpatialReferenceEnvironment Geometry esriGeometry.SpatialReferenceEnvironment 7b5b7020-c4f6-11d1-bc92-0000f875bcce D, E, S
SxAnimationEnvironment 3DAnalyst esri3DAnalyst.SxAnimationEnvironment 592d0b58-82ad-11d5-b29b-00508bcdde28 D, E, S
SxEffectsToolbarEnvironment ArcScene esriArcScene.SxEffectsToolbarEnvironment 80e3f11d-c4bb-11d4-b27e-00508bcdde28 D
SymbologyEnvironment Display esriDisplay.SymbologyEnvironment 65856cd8-ad04-11d3-9fc2-00c04f6bc8dd D, E, S
TrackingEnvironment TrackingAnalyst esriTrackingAnalyst.TrackingEnvironment ef13642c-42da-4095-8a5b-c4f9c6a7bbe3 D, E, S
AGAnimationUtils Animation esriAnimation.AGAnimationUtils 2835514b-1a02-4142-8474-31d48d9063a8 D, E, S
DEUtilities Geoprocessing esriGeoprocessing.DEUtilities f0c2aa3e-b2f1-4208-9843-6a3c70a4680a D, E, S
DEGdbUtilities Geodatabase esriGeodatabase.DEGdbUtilities 48f71b4d-72ce-42aa-a45c-5c180f6e78e8 D, E, S
GPUtilities Geoprocessing esriGeoprocessing.GPUtilities 59e42101-2f33-4b6d-8cee-eed9d98d1957 D, E, S
GPSAUtil SpatialAnalyst esriSpatialAnalyst.GPSAUtil 0c4404c3-276c-475b-bf33-dd35082e5e3a D, E, S
AnimationControlsDialog AnimationUI esriAnimationUI.AnimationControlsDialog 0a44bca2-ec21-4ea3-85d3-a0aae57127e5 D
AnimationCreateKeyframeDialog AnimationUI esriAnimationUI.AnimationCreateKeyframeDialog 8c253bb9-4da2-4ab5-aceb-c6686006c37a D
AnimationFromPathDialog AnimationUI esriAnimationUI.AnimationFromPathDialog dfde1249-74bb-48d3-aae8-b3155f25fd52 D
AnimationLayerGroupDialog AnimationUI esriAnimationUI.AnimationLayerGroupDialog ebf7b926-ee3c-4773-b81e-a7fef23cd7ce D
AnimationManagerDialog AnimationUI esriAnimationUI.AnimationManagerDialog f68848ca-f6af-40aa-8eaf-3305890aee5c D
ErrorDialog SystemUtility esriSystemUtility.ErrorDialog 40accbda-720a-4b17-980b-b173f791958e E (C++ only)
FindDialog CatalogUI esriCatalogUI.FindDialog ad0b37a9-d396-11d3-a6f3-0008c7d3ae50 D
GpsPositionDialog ArcMapUI esriArcMapUI.GpsPositionDialog f56723f3-063d-4b4a-89b9-f03afadf2078 D
IdentifyDialog CartoUI esriCartoUI.IdentifyDialog f8aab776-8b1e-11d3-9f7a-00c04f6bc886 D
NetworkIdentifyDialog NetworkAnalystUI esriNetworkAnalystUI.NetworkIdentifyDialog e4c692c6-f721-4ba4-a000-83893af482ae D
AnimationTypeGlobeLayer GlobeCore esriGlobeCore.AnimationTypeGlobeLayer 7ccba704-3933-4d7a-8e89-4dfee88aa937 D, E, S
AnimationTypeLayer 3DAnalyst esri3DAnalyst.AnimationTypeLayer 24aa4279-adf3-11d5-b2a0-00508bcdde28 D, E, S
AnimationTypeMapLayer Animation esriAnimation.AnimationTypeMapLayer 0a965644-11f1-4901-a0cf-9989bfd27b6d D, E, S
AnimationTypeTimeLayer Animation esriAnimation.AnimationTypeTimeLayer a85b10a9-9eab-4f93-9259-5fbae98000eb D, E, S
DummyGraduatedMarkerLayer Carto esriCarto.DummyGraduatedMarkerLayer 238ccd1a-7fbc-11d2-87dc-0000f8751720 D, E, S
DummyLayer Carto esriCarto.DummyLayer 238ccd19-7fbc-11d2-87dc-0000f8751720 D, E, S
AnimationTypeCamera 3DAnalyst esri3DAnalyst.AnimationTypeCamera 500f4707-a798-11d5-b2a0-00508bcdde28 D, E, S
AnimationTypeGlobeCamera GlobeCore esriGlobeCore.AnimationTypeGlobeCamera d4565495-e2f9-4d89-a8a7-d0b69fd7a424 D, E, S
ExtensionManager System esriSystem.ExtensionManager 6120bc0a-3d90-4274-97ca-713c41f1faff D, E, S
LocatorManager Location esriLocation.LocatorManager e0f10b7a-eb7c-11d2-9f47-00c04f8ed1c4 D, E, S
NADirectionsWindowManager NetworkAnalystUI esriNetworkAnalystUI.NADirectionsWindowManager bc36cf3b-1fc1-461d-92df-ca51cdc9c84c D
RasterAttributeTableManager DataSourcesRaster esriDataSourcesRaster.RasterAttributeTableManager fe143bf3-8d4e-415a-a7e9-a3ac29ab65a7 D, E, S
SchematicProjectMgr Schematic esriSchematic.SchematicProjectMgr c578262a-16c2-4f5a-a526-d738addc8208 D, E, S
SystemHelper System esriSystem.SystemHelper be49d696-3c46-4b81-960b-f67d1bbd238d D, E, S
TMS_MarshalHelper TrackingAnalyst esriTrackingAnalyst.TMS_MarshalHelper 6e5bff39-dcc0-11d6-b861-00010265adc5 D, E, S
GeoDatabaseHelper Geodatabase esriGeodatabase.GeoDatabaseHelper 4e35da0b-c5d1-4ac9-bd62-b36b4155ee4b D, E, S
GPHolder Geoprocessing esriGeoprocessing.GPHolder 602b0005-0ad2-41f1-a831-c640d8586cad D, E, S
MessageLogger System esriSystem.MessageLogger a2e96efd-d501-433b-941f-83447916b8f6 D, E, S
XMLTypeMapper System esriSystem.XMLTypeMapper dcb0f748-2d17-40b5-90c2-7d0b39660405 D, E, S
MetadataSynchronizer Geodatabase esriGeodatabase.MetadataSynchronizer c10124ee-3648-445e-a16b-9d2755fbd690 D, E, S
GxDatabaseExtensions Catalog esriCatalog.GxDatabaseExtensions 27E179F2-4F3E-11D3-9F52-00C04F6BDF06 D
SAExtension SpatialAnalystUI esriSpatialAnalystUI.SAExtension 3c5059fe-9f15-401a-94ed-eed914d73e3e D
TAExtension TrackingAnalystUI esriTrackingAnalystUI.TAExtension d53bf20f-24fb-11d4-b34c-00104ba2abcc D
ServerStyleGallery Display esriDisplay.ServerStyleGallery 9cdcf7da-63b8-4f23-b769-1db1bceadd35 D, E, S
StyleGallery Framework esriFramework.StyleGallery ac0e9827-91cb-11d1-8813-080009ec732a D
MonitorSettings Display esriDisplay.MonitorSettings 9db25fe0-3c75-11d2-aaf6-00c04fa334b3 D, E, S
RasterSettings SpatialAnalystUI esriSpatialAnalystUI.RasterSettings 8ac2f518-ed49-11d2-9f40-00c04f8ed1d7 D
AnimationTypeMapView Animation esriAnimation.AnimationTypeMapView fd22a714-0eef-4312-8703-d81e5476e28a D, E, S
AnimationTypeScene 3DAnalyst esri3DAnalyst.AnimationTypeScene 24aa427a-adf3-11d5-b2a0-00508bcdde28 D, E, S
AppRef * Framework esriFramework.AppRef e1740ec5-9513-11d2-a2df-0000f8774fb5 D
CieLabConversion Display esriDisplay.CieLabConversion 137e39dc-3e98-11d2-aaf7-00c04fa334b3 D, E, S
EngineEditor Controls esriControls.EngineEditor 4afaf64d-0cb2-4adb-bc88-9fb07548d10d E
ErrorMessage SystemUtility esriSystemUtility.ErrorMessage 672fb3aa-c6de-44e0-b767-c53d33ef9879 E (C++ only)
FormatList DataSourcesRaster esriDataSourcesRaster.FormatList 53b7c0b9-41fb-4b00-b51a-fa5cc5b785fe D, E, S
GxCatalogROT CatalogUI esriCatalogUI.GxCatalogROT 04faa368-046b-4cfe-81cb-1c8201f9cad3 D
MyPlaceCollection Controls esriControls.MyPlaceCollection 83307360-8be1-4df2-b301-1e619a965b5c E
RasterStatus DataSourcesRaster esriDataSourcesRaster.RasterStatus 83220700-5844-11d4-8d9b-00c04f5b87b2 D, E, S
TexturePersistenceProperties Geometry esriGeometry.TexturePersistenceProperties 01cfeaf1-4d26-4084-84f8-7d2fda7c40d9 D, E, S
* 每个进程只支持一个对象实例

**D=ArcGIS Desktop;E=ArcGIS Engine;S=ArcGIS for Server **

posted @ 2022-03-01 15:31  误会馋  阅读(184)  评论(0编辑  收藏  举报