07/10/2009 22:01:58
El documento Notas de la versión describe los cambios importantes y los problemas conocidos que debería leer antes de instalar Microsoft Sync Framework 2.0 o solucionar problemas en la aplicación.
-
Instalar Sync Framework
-
Proveedores de base de datos
-
Cambios importantes
-
El comando Compact() puede causar una falta de convergencia de los datos
-
El aprovisionamiento de bases de datos puede causar errores de serialización
-
El aprovisionamiento de bases de datos da error en la cuenta de usuario de privilegios mínimos (LUA) de Windows
-
La aplicación de ejemplo causa una excepción de deserialización
-
Cambios importantes
-
Componentes básicos
-
Cambios importantes
-
Algunos métodos pueden devolver errores que no contienen un mensaje de error útil
-
Las unidades de cambio no se restauran después de un conflicto de eliminación actualización cuando se usan proveedores simples y Filtros de unidades de cambio
-
Las réplicas filtradas no pueden realizar la enumeración completa de la sincronización de recuperación
-
La limpieza de marcadores de exclusión de las réplicas filtradas requiere un procesamiento adicional
-
Los filtros personalizados no se pueden usar con las unidades de cambio
-
Cambios importantes
-
Documentación y ejemplos
1. Instalar Sync Framework
a. Desinstalar la versión preliminar de Sync Framework antes de instalar la versión final
Sync Framework 2.0 no se puede instalar en un equipo que tenga instalada la versión Sync Framework 2.0 Community Technology Preview (CTP). Esto significa que no es posible actualizar desde Sync Framework 2.0 CTP1 o CTP2 a la versión RTM de Sync Framework 2.0. Para instalar Sync Framework 2.0, desinstale primero cualquier versión de Sync Framework 2.0 CTP.
Sync Framework 2.0 se puede instalar, funcionando en paralelo, con Sync Framework 1.0.
2. Proveedores de base de datos
a. Cambios importantes
Entre Sync Framework 1.0 y Sync Framework 2.0 se han producido los cambios siguientes.
-
Se creó la clase base Microsoft.Synchronization.Data.RelationalSyncProvider para encapsular la lógica que es común a todos los proveedores de bases de datos de Sync Framework. Muchos de los miembros de DbSyncProvider fueron movidos a RelationalSyncProvider, pero la superficie de la API general no cambió significativamente. Microsoft.Synchronization.Data.DbSyncProvider, Microsoft.Synchronization.Data.SqlServer.SqlSyncProvider y Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncProvider se han heredado de RelationalSyncProvider.
-
Se ha quitado la colección SyncConflict que estaba disponible desde Microsoft.Synchronization.Data.DbSyncTableProgress. Esto mejoró el rendimiento al reducir el uso de memoria para las sesiones de sincronización con un gran número de conflictos. Ahora se recomienda interactuar con los conflictos sobre una base individual utilizando el evento ApplyChangeFailed por cada proveedor.
Entre Sync Framework 2.0 CTP2 y la versión final de Sync Framework 2.0 se han producido los cambios siguientes.
-
Se quitó la propiedad Microsoft.Synchronization.Data.SqlServer.SqlSyncProviderAdapterConfiguration.PkColumnNames. Ahora en su lugar debería usar la propiedad Microsoft.Synchronization.Data.SqlServer.SqlSyncProviderAdapterConfiguration.Columns.
-
Se cambiaron las colecciones siguientes en las colecciones enumerables para que se adhieran a los patrones existentes para los conocidos tipos ADO.Net, como DataSet:
-
Microsoft.Synchronization.Data.DbSyncTableDescription, que está disponible mediante la propiedad Microsoft.Synchronization.Data.DbSyncScopeDescription.Tables.
-
Microsoft.Synchronization.Data.SqlServer.SqlSyncTableProvisioning, que está disponible mediante la propiedad Microsoft.Synchronization.Data.SqlServer.SqlSyncScopeProvisioning.Tables.
-
Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncTableProvisioning, que está disponible mediante la propiedad Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncScopeProvisioning.Tables.
-
Microsoft.Synchronization.Data.DbSyncTableDescription, que está disponible mediante la propiedad Microsoft.Synchronization.Data.DbSyncScopeDescription.Tables.
-
El método Microsoft.Synchronization.Data.DbSyncColumnDescription.GetInitialParameterName se convirtió a una propiedad para que se conformase a las prácticas recomendadas de diseño de las API. Ahora debe usar en su lugar la propiedad Microsoft.Synchronization.Data.DbSyncColumnDescription.ParameterName.
-
El nombre del método de inicialización de instantánea se cambió a Microsoft.Synchronization.Data.SqlServerCe.SqlCeSyncStoreSnapshotInitialization.InitializeFromSnapshot.
b. El comando Compact() puede causar una falta de convergencia de los datos
Cuando se usa un proveedor de bases de datos para representar una réplica que almacena datos en una base de datos de Microsoft SQL Server Compact y se usa el comando Compact() para reclamar espacio en una base de datos, los valores incorrectos se pueden producir en los metadatos que usa Sync Framework para hacer un seguimiento de los cambios de la base de datos. Si es posible, use el comando Shrink() en lugar del comando Compact() o aplique la revisión que aborda el problema:
c. El aprovisionamiento de bases de datos puede causar errores de serialización
En algunos casos, Sync Framework usa el atributo XmlIgnoreAttribute
cuando se aprovisionan las bases de datos. En las versiones más antiguas de .NET Framework, el uso de XmlIgnoreAttribute
causa la excepción siguiente:
Message: Unable to generate a temporary class (result=1). error CS0200: Property or indexer 'Microsoft.Synchronization.Data.DbSyncColumnDescription.IsNullableSpecified' cannot be assigned to -- it is read only error CS0200: Property or indexer 'Microsoft.Synchronization.Data.DbSyncColumnDescription.IsPrimaryKeySpecified' cannot be assigned to -- it is read only |
Para evitar este problema, asegúrese de que tiene .NET Framework 2.0 SP1 o una versión posterior instalada en el equipo que está ejecutando el proveedor de bases de datos de Sync Framework.
d. El aprovisionamiento de bases de datos da error en la cuenta de usuario de privilegios mínimos (LUA) de Windows
Si el proceso de sincronización se está ejecutando bajo LUA, se produce el error siguiente cuando intenta aprovisionar una base de datos:
Message: Unable to generate a temporary class (result=1). error CS2001: Source file 'D:\WINDOWS\TEMP\ycwdmrz3.0.cs' could not be found error CS2008: No inputs specified |
Este error se produce porque el serializador que usa Sync Framework necesita acceso de lectura y escritura al directorio temporal de Windows, que LUA no permite.
e. La aplicación de ejemplo causa una excepción de deserialización
Cuando la aplicación de ejemplo intenta configurar el tamaño del lote de sincronización en un valor que no sea cero, se producen las excepciones siguientes:
Outer Exception: An unexpected error occurred when applying batch file. Inner Exception: Attempting to deserialize an empty stream. |
Para arreglar la aplicación de ejemplo, modifique el método GetChangeBatch()
en RelationalProviderProxy.cs
(line106) para que la creación de instancias del objeto Filestream
se haga dentro de la declaración If
.
//ORIGINAL CODE string localFileName = Path.Combine(this.localBatchingDirectory.FullName, context.BatchFileName); FileInfo localFileInfo = new FileInfo(localFileName); //Download the file only if it doesn't exist FileStream localFileStream = new FileStream(localFileName, FileMode.Create, FileAccess.Write); if (!localFileInfo.Exists) { byte[] remoteFileContents = this.proxy.DownloadBatchFile(context.BatchFileName); using (localFileStream) { localFileStream.Write(remoteFileContents, 0, remoteFileContents.Length); } } } } //UPDATED CODE string localFileName = Path.Combine(this.localBatchingDirectory.FullName, context.BatchFileName); FileInfo localFileInfo = new FileInfo(localFileName); if (!localFileInfo.Exists) { //Download the file only if doesnt exist FileStream localFileStream = new FileStream(localFileName, FileMode.Create, FileAccess.Write); byte[] remoteFileContents = this.proxy.DownloadBatchFile(context.BatchFileName); using (localFileStream) { localFileStream.Write(remoteFileContents, 0, remoteFileContents.Length); } } |
3. Componentes básicos
a. Cambios importantes
Entre Sync Framework 1.0 y Sync Framework 2.0 se han producido los cambios siguientes.
-
La enumeración Microsoft.Synchronization.FilterType (para código administrado) y la enumeración FILTER_TYPE (para código no administrado) no se usan y se han quitado. Debe quitarse también cualquier referencia a estas enumeraciones que haya en su código.
En el espacio de nombres Microsoft.Synchronization.SimpleProviders se produjeron los siguientes cambios entre Sync Framework 2.0 CTP2 y Sync Framework 2.0 RTM.
-
Se quitaron las siguientes clases y métodos.
-
El constructor AnchorEnumerationContext.
-
El método AnchorEnumerationSimpleSyncProvider.EnumerateItems.
-
El método ISimpleSyncProviderIdGenerator.GenerateNewReplicaId.
-
El método RecoverableErrorReportingContext.RecordRecoverableErrorForChangeUnit.
-
El método SimpleSyncProvider.ChangeReplicaId.
-
La clase ChangeDetectionFailedException.
-
La clase CustomConflictResolutionNotSupportedException.
-
La clase ItemSchemaNotDefinedException.
-
La clase NewItemDoesNotContainAllFieldsException.
-
La clase NoCommonChangeUnitsException.
-
La clase UnknownChangeUnitException.
-
El constructor AnchorEnumerationContext.
-
Se cambió el nombre de los métodos siguientes o se cambiaron los parámetros.
-
Se cambió el nombre del método AnchorEnumerationContext.AutodetectDeletes por el de AnchorEnumerationContext.ReportItemsAndAutodetectDeletes y los parámetros del método se cambiaron.
-
Se cambiaron los parámetros del método AnchorEnumerationSimpleSyncProvider.EnumerateChanges.
-
Se cambiaron los parámetros del método ISimpleSyncProviderIdGenerator.GenerateNewItemId.
-
La clase ItemFieldDictionary ya no implementa la interfaz System.Collections.ICollection.
-
Se cambiaron los parámetros del constructor SimpleSyncServices.
-
Se cambió el nombre del método SimpleSyncServices.CleanupTombstones por el de SimpleSyncServices.CleanupDeletedItems.
-
Se cambiaron los parámetros del constructor UnmanagedSimpleSyncProviderWrapper.UnmanagedSimpleSyncProviderWrapper.
-
Se cambiaron los parámetros del método UnmanagedSimpleSyncProviderWrapper.Initialize.
-
Se cambió el nombre del método AnchorEnumerationContext.AutodetectDeletes por el de AnchorEnumerationContext.ReportItemsAndAutodetectDeletes y los parámetros del método se cambiaron.
-
Las clases siguientes se movieron desde el espacio de nombres Microsoft.Synchronization.SimpleProviders al espacio de nombres Microsoft.Synchronization.
-
ChangeDeferredByProviderException
-
ChangeReplicaIdPendingException
-
DuplicateItemException
-
ItemNotFoundInMetadataStoreException
-
MetadataStoreVersion2RequiredException
-
OptimisticConcurrencyException
-
RecoverableErrorMustFailEntireItemException
-
SimpleProviderInvalidOperationException
-
SimpleProvidersException
-
ChangeDeferredByProviderException
b. Algunos métodos pueden devolver errores que no contienen un mensaje de error útil
Algunos métodos pueden devolver un mensaje de error genérico, como "Exception from HRESULT: 0x80041006", en lugar de una descripción de la causa del error. En la tabla siguiente se enumeran los códigos de error y sus valores. Para las descripciones de estos códigos de error, vea Códigos de error de Sync Framework en la referencia Componentes principales de Sync Framework.
Código de error | Valor de código de error |
---|---|
SYNC_E_ID_FORMAT_MISMATCH |
0x80041000 |
SYNC_E_INVALID_OPERATION |
0x80041001 |
SYNC_E_REPLICA_NOT_FOUND |
0x80041002 |
SYNC_E_CHANGE_COUNT_MISMATCH |
0x80041003 |
SYNC_E_CHANGE_UNIT_COUNT_MISMATCH |
0x80041004 |
SYNC_E_KNOWLEDGE_DECREASED |
0x80041005 |
SYNC_E_CHANGE_NOT_IN_KNOWLEDGE |
0x80041006 |
SYNC_E_ITEM_MUST_EXIST |
0x80041007 |
SYNC_E_HAS_NO_DATA |
0x80041008 |
SYNC_E_CHANGE_NEEDS_KNOWLEDGE |
0x80041009 |
SYNC_E_RANGE_OUT_OF_ORDER |
0x8004100A |
SYNC_E_NOT_EXPECTED_CHANGE |
0x8004100B |
SYNC_E_DESERIALIZATION |
0x8004100C |
SYNC_E_SINGLE_RANGE_ONLY |
0x8004100D |
SYNC_E_ITEM_HAS_CHANGE_UNITS |
0x8004100E |
SYNC_E_ITEM_HAS_NO_CHANGE_UNITS |
0x8004100F |
SYNC_E_ITEM_HAS_NO_VERSION_DATA |
0x80041010 |
SYNC_E_OBJECT_NEEDS_STATE |
0x80041011 |
SYNC_E_FEEDSYNC_INVALID_FEED |
0x80041012 |
SYNC_E_FEEDSYNC_ITEM_NOT_IN_METADATA |
0x80041013 |
SYNC_E_FEEDSYNC_CALLBACK_EXPECTED |
0x80041014 |
SYNC_E_INVALID_VERSION |
0x80041015 |
SYNC_E_DUPLICATE_ITEM |
0x80041016 |
SYNC_E_INVALID_ORDER_FOR_VECTOR_ELEMENTS |
0x80041017 |
SYNC_E_INVALID_SYNC_TIME |
0x80041018 |
SYNC_E_INCOMPLETE_REPLICA_KEY_MAP |
0x80041019 |
SYNC_E_INVALID_REPLICA_KEY |
0x8004101A |
SYNC_E_NEGATIVE_RANGE_EXCEPTION |
0x8004101B |
SYNC_E_BATCH_NEEDS_KNOWLEDGE |
0x8004101C |
SYNC_E_INTERNAL_ERROR |
0x8004101D |
SYNC_E_CHANGE_BATCH_IS_READ_ONLY |
0x8004101E |
SYNC_E_DATA_MODIFIED_CONCURRENTLY |
0x8004101F |
SYNC_E_ON_CREATE_MUST_FAIL_ENTIRE_ITEM |
0x80041020 |
SYNC_E_FILTER_NOT_SUPPORTED |
0x80041021 |
SYNC_E_LOAD_CONFLICT_DATA_FAILED |
0x80041022 |
SYNC_E_INVALID_SERIALIZATION_VERSION |
0x80041023 |
SYNC_E_MARKER_MISMATCH |
0x80041024 |
SYNC_E_FORGOTTEN_KNOWLEDGE_NOT_CONTAINED |
0x80041025 |
SYNC_E_ACTIVE_CHANGE_APPLICATION_CONTEXT |
0x80041026 |
SYNC_E_ITEM_LIST_FILTERED_FULL_ENUMERATION_NOT_SUPPORTED |
0x80041027 |
SYNC_E_FULL_ENUMERATION_MUST_BE_USED |
0x80041028 |
SYNC_E_BATCH_NEEDS_FILTER_FORGOTTEN_KNOWLEDGE |
0x80041029 |
SYNC_E_CONSTRAINT_CONFLICT_NOT_ALLOWED |
0x8004102A |
SYNC_E_SOURCE_DOES_NOT_TRACK_FILTER |
0x8004102B |
c. Las unidades de cambio no se restauran después de un conflicto de eliminación-actualización cuando se usan proveedores simples y Filtros de unidades de cambio
Esta situación se produce cuando se usan proveedores simples y una de las réplicas de la comunidad de sincronización usa un filtro de unidad de cambio. Los pasos que causan esta situación son los siguientes:
-
El elemento I es eliminado de la réplica sin filtrar A y, a continuación, se quita el marcador de exclusión.
-
El elemento I se actualizó en la réplica B. La réplica B usa un filtro de unidad de cambio y, por tanto, no almacena todas las unidades de cambio correspondientes al elemento.
-
La sincronización se realiza utilizando la réplica B como réplica de origen y la réplica A como la de destino.
-
Se ha detectado un conflicto eliminación-actualización en el elemento I y se ha resuelto en favor de la actualización de la réplica B. El elemento I se ha restaurado en la réplica A, pero solo contiene los datos correspondientes a las unidades de cambio que se almacenan en la réplica B. La versión de todas las unidades de cambio se ha actualizado a la nueva versión.
-
La sincronización se realiza de nuevo, esta vez utilizando la réplica C sin filtrar como réplica de origen y la réplica A como la de destino.
-
Las unidades de cambio perdidas del elemento I no se envían desde la réplica C, porque sus versiones en la réplica A son posteriores a sus versiones en la réplica C.
Para evitar esta situación, actualice las unidades de cambio para el elemento I de la réplica C, para que sus versiones sean posteriores a las versiones de la réplica A y, después, sincronice desde la réplica C a la réplica A.
d. Las réplicas filtradas no pueden realizar la enumeración completa de la sincronización de recuperación
Cuando la réplica de destino está obsoleta y debe realizarse la sincronización de recuperación, la réplica de origen debe ser una réplica sin filtrar para recuperar plenamente la réplica obsoleta. Cuando la réplica de origen es una réplica filtrada, el proveedor de origen no debe realizar una enumeración completa, pues se pueden producir resultados inesperados.
En esta situación, la réplica de origen filtrada puede realizar una sincronización parcial con la réplica de destino obsoleta. Para ello, la aplicación especifica FullEnumerationAction.Partial como respuesta al evento FullEnumerationNeeded (para código administrado) o SFEA_PARTIAL_SYNC como respuesta al método de devolución de llamada ISyncCallback::OnFullEnumerationNeeded (para código no administrado). La aplicación también puede canelar la sincronización especificando FullEnumeration.Abort (para código administrado) o SFEA_ABORT (para código no administrado).
e. La limpieza de marcadores de exclusión de las réplicas filtradas requiere un procesamiento adicional
Cuando una réplica filtrada usa la técnica de instantánea para limpiar los marcadores de exclusión, hay que poner mucho cuidado para asegurarse de que el conocimiento de la réplica contenga siempre el conocimiento olvidado de la réplica. Esto se debe a que pueden darse situaciones en las que el conocimiento de una réplica filtrada es reducido por causa de un elemento que se mueve en relación con el filtro.
Limpiar los marcadores de exclusión mediante código administrado
No use la técnica de instantánea para limpiar marcadores de exclusión en una réplica filtrada. En su lugar, realice los pasos siguientes para quitar un marcador de exclusión:
-
Llame a ForgottenKnowledge.ForgetTo, pasando el cambio a la versión del marcador de exclusión que se ha de quitar. Si este método se realiza correctamente, realice el paso 2.
-
Quite el marcador de exclusión desde los metadatos de la réplica.
Limpiar los marcadores de exclusión mediante código no administrado
Para usar la técnica de instantánea para limpiar los marcadores de exclusión en una réplica filtrada, realice los pasos siguientes:
-
Proyecte el conocimiento de instantánea utilizando el conocimiento actual como el conocimiento de plantilla. Para ello, llame a ISyncKnowledge2::ProjectOntoKnowledgeWithPrerequisite en el conocimiento de instantánea, pasando el conocimiento de instantánea correspondiente a pPrerequisiteKnowledge y el conocimiento actual de la réplica correspondiente a pTemplateKnowledge. Use en los pasos siguientes el conocimiento proyectado que devuelve este método.
-
Quitar de la réplica los marcadores de exclusión que están contenidos en el conocimiento de instantánea proyectado.
-
Combinar el conocimiento olvidado de la réplica con el conocimiento de instantánea proyectado y almacenar el resultado como el nuevo conocimiento olvidado de la réplica.
-
Guardar el conocimiento actual de la réplica como el nuevo conocimiento de instantánea.
Se recomienda la técnica de instantánea porque mantiene un conocimiento más pequeño y eficiente. Sin embargo, también se pueden seguir los pasos siguientes para quitar un marcador de exclusión:
-
Llame a IForgottenKnowledge::ForgetToVersion, pasando el cambio a la versión del marcador de exclusión que se ha de quitar. Si este método se realiza correctamente, realice el paso 2.
-
Quite el marcador de exclusión desde los metadatos de la réplica.
Los filtros personalizados no se pueden usar con las unidades de cambio
Cuando un filtro personalizado es usado por un proveedor de origen para enumerar los cambios que contienen las unidades de cambio, se pueden producir resultados inesperados, incluyendo la pérdida de datos. Por ello, cuando un cambio que contiene unidades de cambio se agrega a un lote de cambios filtrado que usa un filtro personalizado, el método ItemChange.AddChangeUnitChange causa una excepción SyncInvalidOperationException (para código administrado) o ISyncChangeBuilder::AddChangeUnitMetadata devuelve SYNC_E_INVALID_OPERATION (para código no administrado).
4. Documentación y ejemplos
a. Los ejemplos deben ser reconfigurados para ejecutarlos en plataformas que no sean x86
Los ejemplos de Sync Framework se configuran para generar en la plataforma x86. Cuando se instala Sync Framework para otra plataforma, como la plataforma x64, los ejemplos dan error al ejecutarse y causan una excepción con el mensaje siguiente: "No se pudo recuperar el generador de clases COM para el componente con CLSID {DBFD020B-D830-4FBE-A927-566B1F57A17A} debido al siguiente error: 80040154".
Para arreglar este problema, reconfigure el ejemplo para generar en la plataforma actual, como la plataforma x64. Vuelva a generar el ejemplo y se ejecutará sin errores.
b. Algunos miembros de API están incorrectamente documentados
-
En la documentación falta una descripción del parámetro filteringType del delegado Microsoft.Synchronization.FilterRequestCallback, del tipo Microsoft.Synchronization.FilteringType. Este parámetro indica el tipo de información incluida en un lote de cambios durante la sincronización filtrada.
-
El valor de retorno de la propiedad Microsoft.Synchronization.Data.DbSyncTableDescription.IsTableMapped se ha descrito incorrectamente en la documentación. Este valor de retorno es false si los valores de la propiedad GlobalName y LocalName son los mismos; en caso contrario es true.
c. Para el chino tradicional, IntelliSense muestra el texto en inglés
Cuando se instala la versión de chino tradicional de Sync Framework 2.0, Microsoft Visual Studio 2008 muestra en inglés el contenido de IntelliSense. Para arreglar este problema, actualícese a Visual Studio 2008 SP1.