방법: 관리 코드를 사용하여 파일 동기화
이 항목에서는 C# 또는 Visual Basic 등의 관리 코드로 Sync Framework File Synchronization Provider를 사용하여 파일 및 하위 폴더를 동기화하는 응용 프로그램을 만드는 방법을 보여 줍니다.
이 항목의 예제에서는 다음과 같은 Sync Framework 형식을 중점적으로 설명합니다.
파일 동기화 이해
Sync Framework는 파일 시스템의 폴더에 들어 있는 파일과 하위 폴더를 동기화하는 데 사용할 수 있는 동기화 공급자를 구현합니다. 이 공급자에서 노출하는 구성 가능한 몇 가지 설정을 통해 동기화를 수행하는 정확한 방법 및 동기화 대상 항목을 세밀하게 제어할 수 있습니다. 응용 프로그램에서는 두 폴더 사이에서 파일을 동기화하기 위해 다음과 같은 기본적인 단계를 수행합니다.
각 폴더를 나타내는 FileSyncProvider 개체를 만듭니다.
두 공급자를 SyncOrchestrator 개체에 전달하고 하나를 원본 공급자로, 다른 하나를 대상 공급자로 지정합니다.
Synchronize를 호출하여 동기화 세션을 시작합니다.
파일 동기화에 대한 자세한 내용은 파일 동기화를 참조하십시오.
예제
이 섹션의 예제 코드는 해당 하위 디렉터리와 이러한 디렉터리의 파일을 포함한 두 디렉터리를 동기화하는 콘솔 응용 프로그램에서 가져온 것입니다. 예제 코드에서는 다음과 같은 태스크를 보여 줍니다.
동기화 옵션을 설정하는 방법
복제본에 대한 변경 내용 검색을 명시적으로 수행하는 방법
동기화에 포함될 항목을 제어하는 필터를 지정하는 방법
동기화 중에 발생할 수 있는 충돌을 처리하는 방법
두 복제본을 동기화하는 방법
이러한 코드 예제를 보여 준 후 빌드하고 실행할 수 있도록 응용 프로그램의 전체 코드도 보여 줍니다.
동기화 옵션 설정
FileSyncOptions 개체를 사용하여 변경 내용을 검색하는 방법 및 동기화 중에 항목을 삭제할지 또는 휴지통으로 이동할지 등 몇 가지 파일 동기화 옵션을 설정할 수 있습니다. 다음 코드 예제에서는 네 가지 옵션을 설정합니다. 그 중 세 가지는 항목 삭제와 관련된 것입니다. ExplicitDetectChanges 옵션을 설정하면 응용 프로그램에서 명시적으로 DetectChanges를 호출하지 않는 한 Sync Framework에서 변경 내용 검색을 수행하지 않습니다. 자세한 내용은 다음 섹션인 "변경 내용 검색 수행"에서 설명합니다.
FileSyncOptions options = FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles | FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
Dim options As FileSyncOptions = _
FileSyncOptions.ExplicitDetectChanges Or FileSyncOptions.RecycleDeletedFiles _
Or FileSyncOptions.RecyclePreviousFileOnUpdates _
Or FileSyncOptions.RecycleConflictLoserFiles
변경 내용 검색 수행
기본적으로 Sync Framework에서는 Synchronize가 호출될 때마다 두 복제본에서 변경 내용 검색을 수행합니다. 변경 내용 검색을 사용하면 Sync Framework가 원본에서 대상으로 전송할 항목과 충돌하는 항목(있을 경우)을 결정할 수 있습니다. ExplicitDetectChanges를 지정하여 변경 내용 검색을 수행할 시점을 제어할 수 있습니다. 다음 코드 예제에서는 Synchronize가 호출되기 전에 각 복제본에 대한 변경 내용 검색을 호출합니다. 이 예제의 목적은 DetectChanges를 보여 주는 것이지만 나중에 응용 프로그램에서 양방향 동기화를 수행할 때 발생하는 두 변경 내용 검색 대신 한 변경 내용 검색을 전달하는 이점이 있음을 알 수 있습니다.
DetectChangesOnFileSystemReplica(
replica1RootPath, filter, options);
DetectChangesOnFileSystemReplica(
replica2RootPath, filter, options);
public static void DetectChangesOnFileSystemReplica(
string replicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider provider = null;
try
{
provider = new FileSyncProvider(replicaRootPath, filter, options);
provider.DetectChanges();
}
finally
{
// Release resources.
if (provider != null)
provider.Dispose();
}
}
DetectChangesOnFileSystemReplica(replica1RootPath, filter, options)
DetectChangesOnFileSystemReplica(replica2RootPath, filter, options)
Public Shared Sub DetectChangesOnFileSystemReplica(ByVal replicaRootPath As String, ByVal filter As FileSyncScopeFilter, _
ByVal options As FileSyncOptions)
Dim provider As FileSyncProvider = Nothing
Try
provider = New FileSyncProvider(replicaRootPath, filter, options)
provider.DetectChanges()
Finally
' Release resources.
If provider IsNot Nothing Then
provider.Dispose()
End If
End Try
End Sub
정적 필터 지정
정적 필터를 설정하여 이름(와일드카드 이름 포함) 및 특성에 따라 파일을 제외할 수 있습니다. 정적 필터를 설정하여 전체 하위 폴더의 내용을 제외할 수도 있습니다. 또는 포함할 명시적 파일 이름 목록(와일드카드 이름 포함)을 지정할 수 있습니다. 모든 필터를 통과한 파일 또는 폴더만 범위에 포함됩니다. 예를 들어 확장명이 .txt인 모든 파일을 범위에서 제외한 경우 범위에 명시적으로 포함할 파일 목록에 MyFile.txt를 지정해도 확장명인 .txt로 인해 MyFile.txt가 제외됩니다.
다음 코드 예제에서는 FileSyncScopeFilter 개체를 사용하여 모든 *.lnk 파일을 제외하는 필터를 만듭니다. 필터는 필터를 만든 공급자와 관계가 없습니다. 필터를 공급자에 연결하려면 FileSyncProvider의 생성자 중 하나에 필터를 전달하거나 ScopeFilter 속성을 설정합니다. 샘플 응용 프로그램에서는 필터가 변경 내용 검색에만 관련이 있으므로 DetectChangesOnFileSystemReplica()
메서드에서 이 작업을 수행합니다. 필터는 공급자와 독립적이므로 동기화 세션마다 하나의 필터만 만들어야 합니다. 공급자에서 여러 필터를 사용하면 데이터 불일치가 발생할 수 있습니다.
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk");
Dim filter As New FileSyncScopeFilter()
filter.FileNameExcludes.Add("*.lnk")
정적 필터뿐만 아니라 공급자에서 발생하는 이벤트를 처리하여 동기화 중에 파일을 제외할 수도 있습니다. 자세한 내용은 동기화되는 파일 제어를 참조하십시오.
충돌 처리
Sync Framework에서는 파일 및 폴더에 대한 동시성 충돌 및 제약 조건 충돌을 검색하고 해결합니다. 동시성 충돌은 두 복제본 간의 마지막 동기화 세션 이후 이러한 복제본에서 같은 항목이 변경될 때 발생합니다. 제약 조건 충돌은 이름이 같은 파일이나 폴더가 두 복제본에 추가될 때 발생합니다. 충돌은 변경 내용이 보다 최신인 파일이나 폴더를 유지하고 변경 내용이 보다 오래된 파일이나 폴더를 삭제 또는 이동하여 해결합니다. 파일의 경우 먼저 발생한 변경 내용과 상관없이 원본 또는 대상이 우선 적용되도록 지정하는 옵션을 사용할 수도 있습니다. 다음 코드 예제에서는 SyncCallbacks 개체를 통해 사용할 수 있는 ItemConflicting 및 ItemConstraint 이벤트에 대한 이벤트 처리기를 등록합니다. 호출되는 메서드는 원본의 입장에서 모든 충돌을 해결하고 콘솔에 정보를 씁니다.
Dim destinationCallbacks As SyncCallbacks = destinationProvider.DestinationCallbacks
AddHandler destinationCallbacks.ItemConflicting, AddressOf OnItemConflicting
AddHandler destinationCallbacks.ItemConstraint, AddressOf OnItemConstraint
SyncCallbacks destinationCallbacks = destinationProvider.DestinationCallbacks;
destinationCallbacks.ItemConflicting += new EventHandler<ItemConflictingEventArgs>(OnItemConflicting);
destinationCallbacks.ItemConstraint += new EventHandler<ItemConstraintEventArgs>(OnItemConstraint);
public static void OnItemConflicting(object sender, ItemConflictingEventArgs args)
{
args.SetResolutionAction(ConflictResolutionAction.SourceWins);
Console.WriteLine("-- Concurrency conflict detected for item " + args.DestinationChange.ItemId.ToString());
}
public static void OnItemConstraint(object sender, ItemConstraintEventArgs args)
{
args.SetResolutionAction(ConstraintConflictResolutionAction.SourceWins);
Console.WriteLine("-- Constraint conflict detected for item " + args.DestinationChange.ItemId.ToString());
}
Public Shared Sub OnItemConflicting(ByVal sender As Object, ByVal args As ItemConflictingEventArgs)
args.SetResolutionAction(ConflictResolutionAction.SourceWins)
Console.WriteLine("-- Concurrency conflict detected for item " & args.DestinationChange.ItemId.ToString())
End Sub
Public Shared Sub OnItemConstraint(ByVal sender As Object, ByVal args As ItemConstraintEventArgs)
args.SetResolutionAction(ConstraintConflictResolutionAction.SourceWins)
Console.WriteLine("-- Constraint conflict detected for item " & args.DestinationChange.ItemId.ToString())
End Sub
두 복제본 동기화
옵션과 필터를 설정한 후 응용 프로그램에서는 SyncOrchestrator를 인스턴스화하고 Synchronize 메서드를 호출하여 두 복제본을 동기화합니다. 다음 코드 예제에서는 각 복제본의 공급자를 지정하고, 옵션을 설정하고, 이벤트 처리기를 등록하고, Upload의 동기화 방향을 지정하고, Synchronize를 호출합니다. 메서드가 두 번 호출되어 복제본 간의 양방향 동기화를 수행합니다.
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, null, options);
SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, null, options);
public static void SyncFileSystemReplicasOneWay(
string sourceReplicaRootPath, string destinationReplicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider destinationProvider = null;
try
{
// Instantiate source and destination providers, with a null filter (the filter
// was specified in DetectChangesOnFileSystemReplica()), and options for both.
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
// Register event handlers so that we can write information
// to the console.
destinationProvider.AppliedChange +=
new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
// Use SyncCallbacks for conflicting items.
SyncCallbacks destinationCallbacks = destinationProvider.DestinationCallbacks;
destinationCallbacks.ItemConflicting += new EventHandler<ItemConflictingEventArgs>(OnItemConflicting);
destinationCallbacks.ItemConstraint += new EventHandler<ItemConstraintEventArgs>(OnItemConstraint);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload; // Upload changes from the source to the destination.
Console.WriteLine("Synchronizing changes to replica: " +
destinationProvider.RootDirectoryPath);
agent.Synchronize();
}
finally
{
// Release resources.
if (sourceProvider != null) sourceProvider.Dispose();
if (destinationProvider != null) destinationProvider.Dispose();
}
}
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, Nothing, options)
SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, Nothing, options)
Public Shared Sub SyncFileSystemReplicasOneWay(ByVal sourceReplicaRootPath As String, _
ByVal destinationReplicaRootPath As String, ByVal filter As FileSyncScopeFilter, _
ByVal options As FileSyncOptions)
Dim sourceProvider As FileSyncProvider = Nothing
Dim destinationProvider As FileSyncProvider = Nothing
Try
' Instantiate source and destination providers, with a null filter (the filter
' was specified in DetectChangesOnFileSystemReplica()), and options for both.
sourceProvider = New FileSyncProvider(sourceReplicaRootPath, filter, options)
destinationProvider = New FileSyncProvider(destinationReplicaRootPath, filter, options)
' Register event handlers so that we can write information
' to the console.
AddHandler destinationProvider.AppliedChange, AddressOf OnAppliedChange
AddHandler destinationProvider.SkippedChange, AddressOf OnSkippedChange
' Use SyncCallbacks for conflicting items.
Dim destinationCallbacks As SyncCallbacks = destinationProvider.DestinationCallbacks
AddHandler destinationCallbacks.ItemConflicting, AddressOf OnItemConflicting
AddHandler destinationCallbacks.ItemConstraint, AddressOf OnItemConstraint
Dim agent As New SyncOrchestrator()
agent.LocalProvider = sourceProvider
agent.RemoteProvider = destinationProvider
agent.Direction = SyncDirectionOrder.Upload
' Upload changes from the source to the destination.
Console.WriteLine("Synchronizing changes to replica: " & destinationProvider.RootDirectoryPath)
agent.Synchronize()
Finally
' Release resources.
If sourceProvider IsNot Nothing Then
sourceProvider.Dispose()
End If
If destinationProvider IsNot Nothing Then
destinationProvider.Dispose()
End If
End Try
End Sub
전체 코드 예제
다음 코드는 이 예제의 전체 코드입니다. 이 섹션의 이전 예제는 이 코드에서 발췌한 것입니다. 이 코드를 실행하려면
콘솔 응용 프로그램 프로젝트를 만들고 코드를 프로젝트에 추가합니다.
Microsoft.Synchronzation.dll 및 Microsoft.Synchronzation.Files.dll에 대한 참조를 추가합니다.
프로젝트를 빌드하여 실행 파일을 만듭니다.
명령줄에서 실행 파일을 실행하여 두 복제본 디렉터리의 파일과 하위 디렉터리를 동기화합니다.
MyExeName.exe \path\to\directoryA \path\to\directoryB
.
using System;
using System.IO;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
namespace Microsoft.Samples.Synchronization
{
class Program
{
public static void Main(string[] args)
{
if (args.Length < 2 ||
string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1]) ||
!Directory.Exists(args[0]) || !Directory.Exists(args[1]))
{
Console.WriteLine(
"Usage: MyExecutableName.exe [valid directory path 1] [valid directory path 2]");
return;
}
string replica1RootPath = args[0];
string replica2RootPath = args[1];
try
{
// Set options for the synchronization session. In this case, options specify
// that the application will explicitly call FileSyncProvider.DetectChanges, and
// that items should be moved to the Recycle Bin instead of being permanently deleted.
FileSyncOptions options = FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles | FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
// Create a filter that excludes all *.lnk files. The same filter should be used
// by both providers.
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk");
// Explicitly detect changes on both replicas before syncyhronization occurs.
// This avoids two change detection passes for the bidirectional synchronization
// that we will perform.
DetectChangesOnFileSystemReplica(
replica1RootPath, filter, options);
DetectChangesOnFileSystemReplica(
replica2RootPath, filter, options);
// Synchronize the replicas in both directions. In the first session replica 1 is
// the source, and in the second session replica 2 is the source. The third parameter
// (the filter value) is null because the filter is specified in DetectChangesOnFileSystemReplica().
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, null, options);
SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, null, options);
}
catch (Exception e)
{
Console.WriteLine("\nException from File Sync Provider:\n" + e.ToString());
}
}
// Create a provider, and detect changes on the replica that the provider
// represents.
public static void DetectChangesOnFileSystemReplica(
string replicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider provider = null;
try
{
provider = new FileSyncProvider(replicaRootPath, filter, options);
provider.DetectChanges();
}
finally
{
// Release resources.
if (provider != null)
provider.Dispose();
}
}
public static void SyncFileSystemReplicasOneWay(
string sourceReplicaRootPath, string destinationReplicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider destinationProvider = null;
try
{
// Instantiate source and destination providers, with a null filter (the filter
// was specified in DetectChangesOnFileSystemReplica()), and options for both.
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
// Register event handlers so that we can write information
// to the console.
destinationProvider.AppliedChange +=
new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
// Use SyncCallbacks for conflicting items.
SyncCallbacks destinationCallbacks = destinationProvider.DestinationCallbacks;
destinationCallbacks.ItemConflicting += new EventHandler<ItemConflictingEventArgs>(OnItemConflicting);
destinationCallbacks.ItemConstraint += new EventHandler<ItemConstraintEventArgs>(OnItemConstraint);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload; // Upload changes from the source to the destination.
Console.WriteLine("Synchronizing changes to replica: " +
destinationProvider.RootDirectoryPath);
agent.Synchronize();
}
finally
{
// Release resources.
if (sourceProvider != null) sourceProvider.Dispose();
if (destinationProvider != null) destinationProvider.Dispose();
}
}
// Provide information about files that were affected by the synchronization session.
public static void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
switch (args.ChangeType)
{
case ChangeType.Create:
Console.WriteLine("-- Applied CREATE for file " + args.NewFilePath);
break;
case ChangeType.Delete:
Console.WriteLine("-- Applied DELETE for file " + args.OldFilePath);
break;
case ChangeType.Update:
Console.WriteLine("-- Applied OVERWRITE for file " + args.OldFilePath);
break;
case ChangeType.Rename:
Console.WriteLine("-- Applied RENAME for file " + args.OldFilePath +
" as " + args.NewFilePath);
break;
}
}
// Provide error information for any changes that were skipped.
public static void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
Console.WriteLine("-- Skipped applying " + args.ChangeType.ToString().ToUpper()
+ " for " + (!string.IsNullOrEmpty(args.CurrentFilePath) ?
args.CurrentFilePath : args.NewFilePath) + " due to error");
if (args.Exception != null)
Console.WriteLine(" [" + args.Exception.Message + "]");
}
// By default, conflicts are resolved in favor of the last writer. In this example,
// the change from the source in the first session (replica 1), will always
// win the conflict.
public static void OnItemConflicting(object sender, ItemConflictingEventArgs args)
{
args.SetResolutionAction(ConflictResolutionAction.SourceWins);
Console.WriteLine("-- Concurrency conflict detected for item " + args.DestinationChange.ItemId.ToString());
}
public static void OnItemConstraint(object sender, ItemConstraintEventArgs args)
{
args.SetResolutionAction(ConstraintConflictResolutionAction.SourceWins);
Console.WriteLine("-- Constraint conflict detected for item " + args.DestinationChange.ItemId.ToString());
}
}
}
Visual Basic 예제에서는 코드가 Main()
메서드에서 MTAThread
특성을 명시적으로 설정합니다. File Synchronization Provider의 경우 응용 프로그램에서 MTA(다중 스레드 아파트) 스레딩 모델을 사용해야 합니다.
Imports System
Imports System.IO
Imports Microsoft.Synchronization
Imports Microsoft.Synchronization.Files
Namespace Microsoft.Samples.Synchronization
Class Program
' File synchronization provider requires applications to use the multithreaded apartment (MTA)
' threading model. This is specified by using the MTAThread attribute.
<MTAThreadAttribute()> _
Public Shared Sub Main(ByVal args As String())
If args.Length < 2 OrElse String.IsNullOrEmpty(args(0)) OrElse String.IsNullOrEmpty(args(1)) OrElse Not Directory.Exists(args(0)) OrElse Not Directory.Exists(args(1)) Then
Console.WriteLine("Usage: MyExecutableName.exe [valid directory path 1] [valid directory path 2]")
Exit Sub
End If
Dim replica1RootPath As String = args(0)
Dim replica2RootPath As String = args(1)
Try
' Set options for the synchronization session. In this case, options specify
' that the application will explicitly call FileSyncProvider.DetectChanges, and
' that items should be moved to the Recycle Bin instead of being permanently deleted.
Dim options As FileSyncOptions = _
FileSyncOptions.ExplicitDetectChanges Or FileSyncOptions.RecycleDeletedFiles _
Or FileSyncOptions.RecyclePreviousFileOnUpdates _
Or FileSyncOptions.RecycleConflictLoserFiles
' Create a filter that excludes all *.lnk files. The same filter should be used
' by both providers.
Dim filter As New FileSyncScopeFilter()
filter.FileNameExcludes.Add("*.lnk")
' Explicitly detect changes on both replicas before syncyhronization occurs.
' This avoids two change detection passes for the bidirectional synchronization
' that we will perform.
DetectChangesOnFileSystemReplica(replica1RootPath, filter, options)
DetectChangesOnFileSystemReplica(replica2RootPath, filter, options)
' Synchronize the replicas in both directions. In the first session replica 1 is
' the source, and in the second session replica 2 is the source. The third parameter
' (the filter value) is null because the filter is specified in DetectChangesOnFileSystemReplica().
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, Nothing, options)
SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, Nothing, options)
Catch e As Exception
Console.WriteLine(vbLf & "Exception from File Sync Provider:" & vbLf & e.ToString())
End Try
End Sub
' Create a provider, and detect changes on the replica that the provider
' represents.
Public Shared Sub DetectChangesOnFileSystemReplica(ByVal replicaRootPath As String, ByVal filter As FileSyncScopeFilter, _
ByVal options As FileSyncOptions)
Dim provider As FileSyncProvider = Nothing
Try
provider = New FileSyncProvider(replicaRootPath, filter, options)
provider.DetectChanges()
Finally
' Release resources.
If provider IsNot Nothing Then
provider.Dispose()
End If
End Try
End Sub
Public Shared Sub SyncFileSystemReplicasOneWay(ByVal sourceReplicaRootPath As String, _
ByVal destinationReplicaRootPath As String, ByVal filter As FileSyncScopeFilter, _
ByVal options As FileSyncOptions)
Dim sourceProvider As FileSyncProvider = Nothing
Dim destinationProvider As FileSyncProvider = Nothing
Try
' Instantiate source and destination providers, with a null filter (the filter
' was specified in DetectChangesOnFileSystemReplica()), and options for both.
sourceProvider = New FileSyncProvider(sourceReplicaRootPath, filter, options)
destinationProvider = New FileSyncProvider(destinationReplicaRootPath, filter, options)
' Register event handlers so that we can write information
' to the console.
AddHandler destinationProvider.AppliedChange, AddressOf OnAppliedChange
AddHandler destinationProvider.SkippedChange, AddressOf OnSkippedChange
' Use SyncCallbacks for conflicting items.
Dim destinationCallbacks As SyncCallbacks = destinationProvider.DestinationCallbacks
AddHandler destinationCallbacks.ItemConflicting, AddressOf OnItemConflicting
AddHandler destinationCallbacks.ItemConstraint, AddressOf OnItemConstraint
Dim agent As New SyncOrchestrator()
agent.LocalProvider = sourceProvider
agent.RemoteProvider = destinationProvider
agent.Direction = SyncDirectionOrder.Upload
' Upload changes from the source to the destination.
Console.WriteLine("Synchronizing changes to replica: " & destinationProvider.RootDirectoryPath)
agent.Synchronize()
Finally
' Release resources.
If sourceProvider IsNot Nothing Then
sourceProvider.Dispose()
End If
If destinationProvider IsNot Nothing Then
destinationProvider.Dispose()
End If
End Try
End Sub
' Provide information about files that were affected by the synchronization session.
Public Shared Sub OnAppliedChange(ByVal sender As Object, ByVal args As AppliedChangeEventArgs)
Select Case args.ChangeType
Case ChangeType.Create
Console.WriteLine("-- Applied CREATE for file " & args.NewFilePath)
Exit Select
Case ChangeType.Delete
Console.WriteLine("-- Applied DELETE for file " & args.OldFilePath)
Exit Select
Case ChangeType.Update
Console.WriteLine("-- Applied OVERWRITE for file " & args.OldFilePath)
Exit Select
Case ChangeType.Rename
Console.WriteLine(("-- Applied RENAME for file " & args.OldFilePath & " as ") & args.NewFilePath)
Exit Select
End Select
End Sub
' Provide error information for any changes that were skipped.
Public Shared Sub OnSkippedChange(ByVal sender As Object, ByVal args As SkippedChangeEventArgs)
Console.WriteLine(("-- Skipped applying " & args.ChangeType.ToString().ToUpper() & " for ") & (If(Not String.IsNullOrEmpty(args.CurrentFilePath), args.CurrentFilePath, args.NewFilePath)) & " due to error")
If args.Exception IsNot Nothing Then
Console.WriteLine(" [" & args.Exception.Message & "]")
End If
End Sub
' By default, conflicts are resolved in favor of the last writer. In this example,
' the change from the source in the first session (replica 1), will always
' win the conflict.
Public Shared Sub OnItemConflicting(ByVal sender As Object, ByVal args As ItemConflictingEventArgs)
args.SetResolutionAction(ConflictResolutionAction.SourceWins)
Console.WriteLine("-- Concurrency conflict detected for item " & args.DestinationChange.ItemId.ToString())
End Sub
Public Shared Sub OnItemConstraint(ByVal sender As Object, ByVal args As ItemConstraintEventArgs)
args.SetResolutionAction(ConstraintConflictResolutionAction.SourceWins)
Console.WriteLine("-- Constraint conflict detected for item " & args.DestinationChange.ItemId.ToString())
End Sub
End Class
End Namespace
참고 항목
참조
Microsoft.Synchronization.Files