Microsoft Sync Framework — полнофункциональная платформа для синхронизации автономных и онлайновых данных, поддержки коллективной работы и автономного доступа к приложениям, сервисам и мобильным устройствам. Она независима от конкретных протоколов и баз данных и включает технологии и утилиты, которые поддерживают роуминг устройств (device roaming), обмен информацией и возможность переводить сетевые данные в автономное состояние перед их последующей синхронизацией в более позднее время.
Sync Framework можно использовать при создании приложений, которые синхронизируют данные из любого хранилища по любому сетевому протоколу. Эта платформа упрощает приложениям, сервисам и устройствам доступ к автономным и онлайновым данным. В Sync Framework заложена расширяемая модель провайдеров, которую можно использовать как с управляемым, так и с неуправляемым кодом для синхронизации данных между двумя источниками.
В этой статье рассматриваются концепции синхронизации и то, как Sync Framework может быть интегрирована в ваши проекты. Конкретнее, я поясню фундаментальные основы синхронизации данных, архитектурные компоненты Sync Framework и способы применения провайдеров синхронизации.
Для работы с Sync Framework и примерами кода в этой статье вам понадобится установить Visual Studio 2010 и исполняющую среду Sync Framework версии 2.0 или выше. Вы можете скачать эту исполняющую среду вместе с Microsoft Sync Framework 2.0 Redistributable Package на сайте Sync Framework Developer Center.
Основы Sync Framework
Sync Framework состоит из четырех основных компонентов: исполняющей среды, сервисов метаданных, провайдеров и участников синхронизации.
Исполняющая среда Sync Framework предоставляет инфраструктуру для синхронизации данных между двумя источниками. Также поставляется SDK, который разработчики могут расширять для реализации собственных провайдеров.
Сервисы метаданных предоставляют инфраструктуру для хранения метаданных синхронизации, которые содержат информацию, используемую в сеансе синхронизации. Метаданные синхронизации включают сведения о версиях, обнаружении изменений и др. Эти метаданные можно также использовать при проектировании разработке собственных провайдеров.
Провайдеры синхронизации применяются для синхронизации данных между репликами или конечными точками. Реплика — это единица синхронизации; она используется для обозначения реального хранилища данных. Например, если вы синхронизируете две базы данных, тогда каждая из баз данных будет считаться репликой. Реплика определяется по уникальному идентификатору, который называют ключом реплики. Конечная точка также ссылается на хранилище данных. Подробнее о провайдерах мы поговорим позже.
Участником (participant) называют источник, откуда можно извлечь данные, подлежащие синхронизации. Участники бывают трех видов:полные, частичные и простые.
Полные участники — устройства, способные создавать новые хранилища данных, хранить метаданные синхронизации и выполнять синхронизирующие приложения. Примеры таких участников — настольные компьютеры, лэптопы и планшеты. Полный участник может синхронизировать данные с другим участником.
Частичные участники — устройства, которые могут создавать новые хранилища данных и хранить метаданные синхронизации, но не позволяющие выполнять синхронизирующие приложения. Частичным участником может быть USB-накопитель или смартфон. Заметьте, что частичный участник может синхронизировать данные с полным, но не с другим частичным участником.
Простые участники включают устройства, не умеющие хранить новые данные или выполнять приложения, а способные лишь предоставлять запрошенную информацию. Примеры простых участников — RSS-каналы или веб-сервисы Amazon и Google.
Провайдеры синхронизации
Провайдер синхронизации — компонент, который участвует в процессе синхронизации и обеспечивает синхронизацию данных одной реплики с данными других реплик. У вас должен быть один провайдер на каждую реплику.
Для синхронизации данных запускается сеанс синхронизации. В этом сеансе приложение подключается к провайдерам синхронизации для источника и получателя для передачи данных между репликами.
После запуска сеанса синхронизации провайдер получателя предоставляет информацию о своем хранилище данных провайдеру источника. Последний определяет, какие изменения в реплике-источнике не известны реплике-получателю, а затем передает список таких изменений провайдеру получателя. Тот распознает любые конфликты между собственными элементами и присутствующими в списке, а потом применяет изменения к своему хранилищу данных. Механизм Sync Framework упрощает весь этот процесс синхронизации.
Sync Framework поддерживает три провайдера по умолчанию для синхронизации баз данных, файловых систем и каналов:
- провайдер синхронизации для источников данных с поддержкой ADO.NET;
- провайдер синхронизации для RSS- и Atom-каналов;
- провайдер синхронизации для файлов и папок.
Вы также можете расширить Sync Framework для создания собственного провайдера синхронизации, который будет поддерживать обмен информацией между устройствами и приложениями.
Провайдер синхронизации баз данных (прежнее название в Sync Framework 1.0 — Sync Services for ADO.NET) поддерживает источники данных с поддержкой ADO.NET. Вы можете создавать приложения с поддержкой отсоединенных данных, что облегчает синхронизацию между источниками данных с поддержкой ADO.NET, например SQL Server. Поддерживаются роуминг, обмен и автономные данные. Любая база данных, использующая провайдер, может участвовать в процессе синхронизации с другими источниками данных, которые поддерживаются Sync Framework, в том числе файловыми системами, веб-сервисами и даже собственными хранилищами данных.
Провайдер веб-синхронизации (ранее Sync Services for FeedSync) поддерживает RSS- и ATOM-каналы. До FeedSync эта технология была известна под названием Simple Sharing Extensions и изначально была спроектирована Рэем Оззи (Ray Ozzie). Заметьте, что провайдер веб-синхронизации не заменяет существующие технологии вроде RSS- или Atom-каналов. Вместо этого он предлагает простой способ добавления средств синхронизации в существующие RSS- или Atom-каналы, чтобы они могли использоваться другими приложениями или сервисами независимо от платформы или устройства.
Провайдер синхронизации файлов (ранее Sync Services for File Systems) поддерживает синхронизацию файлов и папок в одной системе или между системами в сети. Он может использоваться для синхронизации файлов и папок в одной системе или в различных системах в сети. Вы можете синхронизировать файлы и папки в системах с файловыми системами NTFS, FAT или SMB. Провайдер использует модель метаданных Sync Framework для включения одноранговой (peer-to-peer) синхронизации файловых данных с поддержкой произвольных топологий (клиент-сервер, ячеистая сеть и одноранговые системы), в том числе съемных носителей. Провайдер синхронизации файлов также поддерживает инкрементальную синхронизацию, распознавание конфликтов и изменений, режимы с предварительным просмотром и без, а также фильтрацию и пропуск определенных файлов.
Работа со встроенными провайдерами синхронизации
В этом разделе я продемонстрирую, как работать со встроенными провайдерами синхронизации, чтобы реализовать простое приложение для синхронизации содержимого двух папок в системе.
Создать провайдер синхронизации файлов можно с помощью класса FileSyncProvider. Он расширяет класс UnManagedSyncProvider и реализует интерфейс IDisposable. Класс FileSyncScopeFilter позволяет включать или исключать файлы и папки, которые будут участвовать в процессе синхронизации.
FileSyncProvider распознает изменения в реплике, используя метаданные синхронизации. Эти метаданные содержат информацию обо всех файлах и папках, участвующих в синхронизации. На самом деле существует два вида метаданных синхронизации: метаданные реплики (replica metadata) и элемента (item metadata). Провайдер синхронизации файлов хранит метаданные для всех файлов и папок, участвующих в синхронизации. Впоследствии информация о размерах файлов, атрибутах и времени последнего обращения используется для распознавания изменений.
Откройте Visual Studio 2010 и создайте новый проект Windows Presentation Foundation (WPF). Сохраните его под именем SyncFiles. Откройте файл MainWindow.xaml и создайте WPF-форму по аналогии с тем, что показано на рис. 1.
Рис. 1. Пример приложения Sync
Как видите, у вас есть элементы управления для выбора папок-источников и папок-приемников. Также имеются элементы управления для отображения статистики синхронизации и содержимого папок.
Щелкните правой кнопкой мыши проект в Solution Explorer, выберите Add Reference и добавьте сборки Microsoft.Synchronization.
Теперь добавьте новый метод GetReplicaID в файл MainWindow.xaml.cs для возврата GUID, как показано в коде на рис. 2. Метод Synchronize, вызванный из экземпляра SyncOrchestrator, создает файл метаданных filesync.metadata в каждой папке или реплике, используя уникальный GUID. Метод GetReplicaID сохраняет этот GUID в файле, чтобы при следующем вызове данного метода не генерировать новый GUID для конкретной папки. Метод GetReplicaID сначала проверяет, содержится ли в файле идентификатор реплики. Если такого файла нет, создается новый идентификатор реплики и сохраняется в файле. А если файл есть (поскольку идентификатор реплики для этой папки уже был сгенерирован), метод возвращает идентификатор реплики из файла.
Рис. 2. GetReplicaID
private Guid GetReplicaID(string guidPath) {
if (!File.Exists(guidPath)) {
Guid replicaID = Guid.NewGuid();
using (FileStream fileStream =
File.Open(guidPath, FileMode.Create)) {
using (StreamWriter streamWriter =
new StreamWriter(fileStream)) {
streamWriter.WriteLine(replicaID.ToString());
}
}
return replicaID;
}
else {
using (FileStream fileStream =
File.Open(guidPath, FileMode.Open)) {
using (StreamReader streamReader =
new StreamReader(fileStream)) {
return new Guid(streamReader.ReadLine());
}
}
}
}
Затем добавьте метод GetFilesAndDirectories, возвращающий список файлов и папок в реплике (рис. 3). Имя папки следует передавать как параметр.
Рис. 3. Получение файлов и папок реплкики
private List<string> GetFilesAndDirectories(String directory) {
List<String> result = new List<String>();
Stack<String> stack = new Stack<String>();
stack.Push(directory);
while (stack.Count > 0) {
String temp = stack.Pop();
try {
result.AddRange(Directory.GetFiles(temp, "*.*"));
foreach (string directoryName in
Directory.GetDirectories(temp)) {
stack.Push(directoryName);
}
}
catch {
throw new Exception("Error retrieving file or directory.");
}
}
return result;
}
Этот метод будет использоваться для отображения списка файлов и папок в папках-источниках и папках-приемниках до и после синхронизации. Методы PopulateSourceFileList и PopulateDestinationFileList вызывают GetFilesAndDirectories для заполнения окон списков, где показываются файлы и каталоги в папках-источниках и папках-приемниках (детали см. в исходном коде к этой статье).
Обработчики событий btnSource_Click и btnDestination_Click позволяют выбирать папки-источники и папки-приемники. Оба метода опираются на класс FolderBrowser для вывода диалогового окна, из которого пользователь может выбрать папки-источники и папки-приемники. Полный исходный код класса FolderBrowser доступен в пакете кода, который можно скачать для этой статьи.
Теперь нужно написать обработчик события Click элемента управления Button, который начинает с отключения кнопки перед запуском синхронизации. Далее он вызывает метод Synchronize, передавая в параметрах пути к источнику и получателю. Наконец, запускается процесс синхронизации, перехватываются любые ошибки и по окончании синхронизации кнопка вновь делается доступной:
btnSyncFiles.IsEnabled = false;
// Disable the button before synchronization starts
Synchronize(sourcePath, destinationPath);
btnSyncFiles.IsEnabled = true;
// Enable the button after synchronization is complete
Метод Synchronize принимает пути к источнику и получателю и синхронизирует содержимое двух реплик. В методе Synchronize я принимаю экземпляр класса SyncOperationStatistics, чтобы извлечь статистическую информацию о процессе синхронизации:
SyncOperationStatistics syncOperationStatistics;
Я также создаю провайдеры синхронизации источника и получателя, создаю экземпляр SyncOrchestrator под именем synchronizationAgent, назначаю GUID-идентификаторы репликам (источнику и получателю) и подключаю два провайдера. SyncOrchestrator отвечает за координацию сеанса синхронизации:
sourceReplicaID =
GetReplicaID(Path.Combine(source,"ReplicaID"));
destinationReplicaID =
GetReplicaID(Path.Combine(destination,"ReplicaID"));
sourceProvider =
new FileSyncProvider(sourceReplicaID, source);
destinationProvider =
new FileSyncProvider(destinationReplicaID, destination);
SyncOrchestrator synchronizationAgent =
new SyncOrchestrator();
synchronizationAgent.LocalProvider = sourceProvider;
synchronizationAgent.RemoteProvider = destinationProvider;
Наконец, я запускаю процесс синхронизации, перехватываю любые ошибки и освобождаю ресурсы, как только необходимость в них отпадает рис. 4. В исходный код для этой статьи входит полный проект с обработкой ошибок и другими деталями реализации.
Рис. 4. Синхронизация реплик
try {
syncOperationStatistics = synchronizationAgent.Synchronize();
// Assign synchronization statistics to the lstStatistics control
lstStatistics.Items.Add("Download Applied: " +
syncOperationStatistics.DownloadChangesApplied.ToString());
lstStatistics.Items.Add("Download Failed: " +
syncOperationStatistics.DownloadChangesFailed.ToString());
lstStatistics.Items.Add("Download Total: " +
syncOperationStatistics.DownloadChangesTotal.ToString());
lstStatistics.Items.Add("Upload Total: " +
syncOperationStatistics.UploadChangesApplied.ToString());
lstStatistics.Items.Add("Upload Total: " +
syncOperationStatistics.UploadChangesFailed.ToString());
lstStatistics.Items.Add("Upload Total: " +
syncOperationStatistics.UploadChangesTotal.ToString());
}
catch (Microsoft.Synchronization.SyncException se) {
MessageBox.Show(se.Message, "Sync Files - Error");
}
finally {
// Release resources once done
if (sourceProvider != null)
sourceProvider.Dispose();
if (destinationProvider != null)
destinationProvider.Dispose();
}
Вы также можете создавать отчеты о ходе процесса синхронизации. Для реализации такой функциональности придерживайтесь следующей схемы.
- Зарегистрируйте обработчик события ApplyingChange.
- Включите режим предварительного просмотра (preview mode), установив свойство PreviewMode объекта FileSyncProvider в true.
- Создайте целочисленный счетчик и увеличивайте его значение на 1 при каждом срабатывании события ApplyingChange.
- Запустите процесс синхронизации.
- Установите свойство PreviewMode объекта FileSyncProvider в false для отключения режима предварительного просмотра.
- Вновь запустите процесс синхронизации.
Фильтрация и пропуск определенных файлов
При синхронизации с применением Sync Framework некоторые файлы пропускаются автоматически, в том числе Desktop.ini и Thumbs.db, файлы с атрибутами «системный» и «скрытый», а также файлы метаданных. Вы можете применять статические фильтры для управления составом синхронизируемых файлов и папок. Точнее, эти фильтры позволяют исключать файлы, которые не должны участвовать в процессе синхронизации.
Чтобы использовать статические фильтры, создайте экземпляр класса FileSyncScopeFilter и передайте включающие и исключающие фильтры как параметры его конструктору. Вы также можете вызывать метод FileNameExcludes.Add своего экземпляра FileSyncScopeFilter для исключения одного или более файлов из сеанса синхронизации. Затем вы можете передать этот экземпляр FileSyncScopeFilter при создании своего экземпляра FileSyncProvider. Вот пример:
FileSyncScopeFilter fileSyncScopeFilter =
new FileSyncScopeFilter();
fileSyncScopeFilter.FileNameExcludes.Add("filesync.id");
FileSyncProvider fileSyncProvider =
new FileSyncProvider(Guid.NewGuid(),
"D:\\MyFolder",fileSyncScopeFilter,FileSyncOptions.None);
Аналогично вы можете исключить все файлы с расширением .lnk из процесса синхронизации:
FileSyncScopeFilter fileSyncScopeFilter =
new FileSyncScopeFilter();
fileSyncScopeFilter.FileNameExcludes.Add("*.lnk");
Вы даже можете использовать FileSyncOptions для явного задания параметров сеанса синхронизации:
FileSyncOptions fileSyncOptions =
FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles |
FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
Чтобы пропустить один или более файлов при синхронизации, зарегистрируйте обработчик события AppliedChange и установите свойство SkipChange в true:
FileSyncProvider fileSyncProvider;
fileSyncProvider.AppliedChange +=
new EventHandler (OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler (OnSkippedChange);
Теперь можно реализовать обработчик события OnAppliedChange для отображения происходящих изменений:
public static void OnAppliedChange(
object sender, AppliedChangeEventArgs args) {
switch (args.ChangeType) {
case ChangeType.Create:
Console.WriteLine("Create " + args.NewFilePath);
break;
case ChangeType.Delete:
Console.WriteLine("Delete" + args.OldFilePath);
break;
case ChangeType.Overwrite:
Console.WriteLine("Overwrite" + args.OldFilePath);
break;
default:
break;
}
}
Заметьте, что этот пример упрощен для ясности. Более надежная реализация включена в исходный код, который можно скачать к этой статье.
Чтобы узнавать, почему в сеансе синхронизации был пропущен определенный файл, вы можете реализовать обработчик события OnSkippedChange:
public static void OnSkippedChange(
object sender, SkippedChangeEventArgs args) {
if (args.Exception != null)
Console.WriteLine("Synchronization Error: " +
args.Exception.Message);
}
Скомпилируйте и запустите приложение. Щелкните кнопку Source Folder и выберите папку-источник. Аналогичным образом выберите папку-приемник, щелкнув кнопку Destination Folder. Вы увидите, что перед синхронизацией в соответствующих окнах списков отображаются перечни файлов в каждой папке (рис. 1). Окно списка Synchronization Statistics на данном этапе пустое, так как синхронизация еще не началась.
Теперь щелкните кнопку Synchronize для запуска синхронизации. После синхронизации папки-источники и папки-приемника в соответствующих окнах списков появится содержимое обеих папок. В списке Synchronization Statistics появится информация о завершенных задачах (рис. 5).
Рис. 5. Синхронизация завершена
Обработка конфликтов
Sync Framework управляет всеми сложностями синхронизации на основе временных меток, в том числе отложенными конфликтами (deferred conflicts), сбоями, прерываниями и зацикливанием. Для обработки конфликтов данных в ходе сеанса синхронизации Sync Framework следует одной из стратегий.
- Source Wins (победа отдается источнику): изменения, внесенные в хранилище данных на стороне источника, всегда считаются приоритетными в случае конфликта.
- Destination Wins (победа отдается получателю): изменения, внесенные в хранилище данных на стороне получателя, всегда считаются приоритетными в случае конфликта.
- Merge (объединение): изменения в случае конфликта объединяются.
- Регистрация конфликта: это стратегия, при которой разрешение конфликта откладывается или регистрируется в журнале.
Понимание схемы синхронизации
Экземпляр SyncOrchestrator управляет сеансом синхронизации и потоком данных в этом сеансе. Поток синхронизации всегда направлен в одну сторону, и вы имеете дело с провайдером источника, подключенным к реплике-источнику, и провайдером получателя, подключенным к реплике-приемнику. Первый шаг — создание этих провайдеров, назначение им уникальных идентификаторов реплик и подключение двух провайдеров к репликам (источнику и приемнику):
FileSyncProvider sourceProvider =
new FileSyncProvider(sourceReplicaID, @"D:\Source");
FileSyncProvider destinationProvider =
new FileSyncProvider(destinationReplicaID, @"D:\Destination");
Затем создайте экземпляр SyncOrchestrator и подключите к нему оба провайдера. Вызов метода Synchronize экземпляра SyncOrchestrator создает связь между провайдерами источника и приемника:
SyncOrchestrator syncAgent = new SyncOrchestrator();
syncAgent.LocalProvider = sourceProvider;
syncAgent.RemoteProvider = destProvider;
syncAgent.Synchronize();
С этого момента Sync Framework может выполнять ряд вызовов в процессе синхронизации. Давайте рассмотрим их.
Для провайдеров источника и получателя вызывается BeginSession, который указывает, что провайдер синхронизации присоединяется к сеансу синхронизации. Заметьте, что метод BeginSession генерирует исключение InvalidOperationException, если сеанс не удается запустить или если провайдер инициализирован неправильно:
public abstract void BeginSession(
SyncProviderPosition position,
SyncSessionContext syncSessionContext);
Sync Framework вызывает GetSyncBatchParameters экземпляра провайдера получателя. Этот провайдер возвращает известную ему информацию (компактное представление версий или изменений в конкретной реплике) и запрошенный размер пакета (batch size). Данный метод имеет два выходных (out) параметра:batchSize и knowledge:
public abstract void GetSyncBatchParameters(
out uint batchSize,
out SyncKnowledge knowledge);
Далее Sync Framework вызывает GetChangeBatch экземпляра провайдера источника. Этот метод имеет два входных параметра (batchSize и destinationKnowledge):
public abstract ChangeBatch GetChangeBatch(
uint batchSize,
SyncKnowledge destinationKnowledge,
out object changeDataRetriever);
и один выходной, через который передает сводку об измененных версиях и свою информацию о реплике-источнике провайдеру получателю в виде объекта changeDataRetriever:
Для обработки изменений вызывается метод ProcessChangeBatch провайдера получателя:
public abstract void ProcessChangeBatch(
ConflictResolutionPolicy resolutionPolicy,
ChangeBatch sourceChanges,
object changeDataRetriever,
SyncCallbacks syncCallbacks,
SyncSessionStatistics sessionStatistics);
Для каждого изменения в пакете вызывается SaveItemChange провайдера получателя. Если вы реализуете собственный провайдер, то должны обновлять реплику-приемник изменениями, переданными от реплики-источника, а затем обновлять метаданные в хранилище информацией от источника:
void SaveItemChange(SaveChangeAction saveChangeAction,
ItemChange change, SaveChangeContext context);
Для сохранения информации в хранилище метаданных вызывается StoreKnowledgeForScope провайдера получателя:
public void StoreKnowledgeForScope(
SyncKnowledge knowledge,
ForgottenKnowledge forgottenKnowledge)
Чтобы сообщить, что провайдер намерен отключиться от сеанса синхронизации, к которому он был ранее подключен, вызывается EndSession как провайдера источника, так и провайдера получателя:
public abstract void EndSession(
SyncSessionContext syncSessionContext);
Собственные провайдеры синхронизации
Теперь вы знаете, как работают провайдеры синхронизации, предлагаемые по умолчанию. Как я уже упоминал, вы можете реализовать собственные провайдеры синхронизации. Такой провайдер расширяет функциональность встроенного провайдера. Он может понадобиться вам, если для хранилища данных, подлежащего синхронизации, не предусмотрен стандартный провайдер. Вы также можете создать собственный провайдер синхронизации, который реализует единицы изменений для более тонкого управления отслеживанием изменений и для уменьшения количества конфликтов.
Для разработки собственного провайдера создайте класс, расширяющий абстрактный класс KnowledgeSyncProvider и реализующий интерфейсы IChangeDataRetriever и INotifyingChangeApplierTarget. Заметьте, что эти классы и интерфейсы являются частью пространства имен Microsoft.Synchronization.
Рассмотрим вкратце пример собственного провайдера.Допустим, вам нужно реализовать провайдер для синхронизации данных между базами данных. Это лишь обзор простого примера, и его можно расширить для поддержки куда более сложных вариантов применения.
Начните с создания трех баз данных в SQL Server 2008 (я назвал их ReplicaA, ReplicaB и ReplicaC) и создайте в каждой базе данных таблицу Student. Собственный провайдер будет синхронизировать записи между тремя таблицами Student. Далее создайте сущность Student для выполнения CRUD-операций над таблицей Student.
Напишите класс Student с полями StudentID, FirstName и LastName, а также со всеми вспомогательными методами, необходимыми для выполнения CRUD-операций в базе данных:
public class Student {
public int StudentID { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
//Helper methods for CRUD operations
...
}
Создайте класс CustomDBSyncProvider и расширьте его от KnowledgeSyncProvider, IChangeDataRetriever, INotifyingChangeApplierTarget и IDisposable:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Synchronization;
using Microsoft.Synchronization.MetadataStorage;
public class CustomDBSyncProvider : KnowledgeSyncProvider,
IChangeDataRetriever,
INotifyingChangeApplierTarget,IDisposable {
...
Реализуйте необходимые методы в своем провайдере синхронизации баз данных и создайте UI для отображения содержимого каждой таблицы Student (детали см. в пакете исходного кода, который можно скачать для этой статьи).
Теперь создайте три экземпляра собственного провайдера и подключите их к таблицам Student в базах данных. Наконец, синхронизируйте содержимой одной реплики с другой с помощью собственного провайдера синхронизации:
private void Synchronize(
CustomDBSyncProvider sourceProvider,
CustomDBSyncProvider destinationProvider) {
syncAgent.Direction =
SyncDirectionOrder.DownloadAndUpload;
syncAgent.LocalProvider = sourceProvider;
syncAgent.RemoteProvider = destinationProvider;
syncStatistics = syncAgent.Synchronize();
}
Заключение
Как вы убедились, Sync Framework предоставляет простую, но полнофункциональную платформу синхронизации, которая обеспечивает бесшовную синхронизацию между автономными и онлайновыми данными. Ее можно применять для синхронизации данных независимо от протокола и конкретного хранилища данных. Ее также можно задействовать для простого резервного копирования файлов или легко расширить под использование в сетях, предназначенных для коллективной работы. Кроме того, вы можете создавать собственные провайдеры синхронизации таких источников данных, для которых нет встроенной поддержки.