EDN Admin
Well-known member
To start:
Using Sync Framework 2.1 for the first time. First ever application at all in C#.
Not a school project or commercial entity, but a pro bono military application to help out some buddies sync their publications. I was pushed towards the Sync Framework because of several reasons. Problem is: I dont know how to implement a background worker. I know Sync Toy does what I am trying to do, but I have to submit the source code, and it needs to be hard coded for some things. So its a "no deal."
All clients on the network is Win7, 100/1000Mb LAN, and decent specs.
Requirements:
-One-Way Sync only, but from three different sources on the LAN...UNC network paths. Destination is one or more plugged in USB hard drives (spinning, not flash).
-Overwrite destination on conflict.
-Progress Bar, works now, but only for one of the syncs, and locks up upon sync start.
-Would love to add a semi-accurate remaining ETA, either time/files/bytes/etc.
-Good coding practice, but so far not my strong suit, but Im working on it.
-Cancel ability (hence the background worker)
I have the form and most of the code in a semi-working fashion, I didnt want to post it all here, but here is the sync class I am working from. Any help would be appreciated. I can share via Team Foundation, or send the entire solution to get a better picture of how Ive messed it up. Really just hoping to get some ideas on how to streamline and get it to a usable fashion. Better Multi-threading would be cool, making the drop-downs for source/dest work better can happen later, and some persistent user settings would be awesome, but not rush.
So far, I love the way sync framework compares files, but I get the feeling Im not doing the preview mode for progress bar and actual sync properly.
Obviously, this isnt a use for any kind of profit, but if someone is willing to help me get to a good point, id be happy to send you an American Flag flown over the skies of Afghanistan or something cool like that!using System;
using Microsoft.Synchronization.Files;
using Microsoft.Synchronization;
namespace SyncFramework1
{
/// <summary>
/// Perform an optimised file sync
/// </summary>
public class OptimisedSyncHelper
{
#region Events and Delegates
public event EventHandler<RequiredChangeInformationEventArgs> RequiredChangeInformation;
public event EventHandler<DetectingChangesEventArgs> DetectingChanges;
public event EventHandler<AppliedChangeEventArgs> AppliedChange;
public event EventHandler<SkippedChangeEventArgs> SkippedChange;
#endregion
#region Public Implementation
/// <summary>
/// Perform the synchronisation
/// </summary>
/// <param name="sourceFolder </param>
/// <param name="targetFolder </param>
/// <param name="provideProgressInformation </param>
/// <param name="uploadStatistics </param>
/// <param name="downloadStatistics </param>
public void PerformSynchronisation(string sourceFolder, string targetFolder, out SyncOperationStatistics uploadStatistics, out SyncOperationStatistics downloadStatistics)
{
// Set options for the sync operation
FileSyncOptions options = FileSyncOptions.ExplicitDetectChanges | FileSyncOptions.RecycleDeletedFiles | FileSyncOptions.RecyclePreviousFileOnUpdates | FileSyncOptions.RecycleConflictLoserFiles;
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk"); // Exclude all *.lnk files
// Explicitly detect changes on both replicas upfront, to avoid two change detection passes for the two-way sync
DetectChangesOnFileSystemReplica(sourceFolder, filter, options);
DetectChangesOnFileSystemReplica(targetFolder, filter, options);
// Sync in both directions
uploadStatistics = SyncFileSystemReplicasOneWay(sourceFolder, targetFolder, filter, options, false);
downloadStatistics = SyncFileSystemReplicasOneWay(targetFolder, sourceFolder, filter, options, false);
// If we want preview/progress information - pass to the consumer
int totalChangesRequired = uploadStatistics.UploadChangesTotal + uploadStatistics.DownloadChangesTotal + downloadStatistics.UploadChangesTotal + downloadStatistics.DownloadChangesTotal;
OnRequiredChangeInformation(totalChangesRequired);
uploadStatistics = SyncFileSystemReplicasOneWay(sourceFolder, targetFolder, filter, options, false);
downloadStatistics = SyncFileSystemReplicasOneWay(targetFolder, sourceFolder, filter, options, false);
}
#endregion
#region Event Wrappers
/// <summary>
/// Raise an event if necessary indicating the number of changes required.
/// </summary>
/// <param name="totalChangesRequired </param>
private void OnRequiredChangeInformation(int totalChangesRequired)
{
if (RequiredChangeInformation != null)
{
RequiredChangeInformation(this, new RequiredChangeInformationEventArgs(totalChangesRequired));
}
}
/// <summary>
/// Raise an event if necessary indicating that a detecting change operation is occuring
/// </summary>
/// <param name="sender </param>
/// <param name="e </param>
private void OnDetectingChanges(object sender, DetectingChangesEventArgs e)
{
if (DetectingChanges != null)
{
DetectingChanges(sender, e);
}
}
/// <summary>
/// Report that an operation has been performed
/// </summary>
/// <param name="sender </param>
/// <param name="args </param>
private void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
if (AppliedChange != null)
{
AppliedChange(this, args);
}
}
/// <summary>
/// Report that an operation was skipped.
/// </summary>
/// <param name="sender </param>
/// <param name="args </param>
private void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
if (SkippedChange != null)
{
SkippedChange(this, args);
}
}
#endregion
#region Private Implementation
/// <summary>
/// Perform a DetectChange operation on a FileSyncProvider.
/// </summary>
/// <param name="replicaRootPath </param>
/// <param name="filter </param>
/// <param name="options </param>
private void DetectChangesOnFileSystemReplica(string replicaRootPath, FileSyncScopeFilter filter, FileSyncOptions options)
{
using (FileSyncProvider provider = new FileSyncProvider(replicaRootPath, filter, options))
{
provider.DetectingChanges += new EventHandler<DetectingChangesEventArgs>(OnDetectingChanges);
provider.DetectChanges();
}
}
/// <summary>
/// Perform a 1 way sync
/// </summary>
/// <param name="sourceFolder </param>
/// <param name="targetFolder </param>
/// <param name="filter </param>
/// <param name="options </param>
/// <param name="preview </param>
/// <returns></returns>
private SyncOperationStatistics SyncFileSystemReplicasOneWay(string sourceFolder, string targetFolder, FileSyncScopeFilter filter, FileSyncOptions options, bool preview)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider targetProvider = null;
try
{
sourceProvider = new FileSyncProvider(sourceFolder, filter, options);
targetProvider = new FileSyncProvider(targetFolder, filter, options);
sourceProvider.PreviewMode = preview;
targetProvider.PreviewMode = preview;
targetProvider.AppliedChange += new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
targetProvider.SkippedChange += new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = targetProvider;
agent.Direction = SyncDirectionOrder.Upload; // Sync source to destination
return agent.Synchronize();
}
finally
{
// Release resources
if (sourceProvider != null)
{
sourceProvider.Dispose();
}
if (targetProvider != null)
{
targetProvider.Dispose();
}
}
}
#endregion
}
}
View the full article
Using Sync Framework 2.1 for the first time. First ever application at all in C#.
Not a school project or commercial entity, but a pro bono military application to help out some buddies sync their publications. I was pushed towards the Sync Framework because of several reasons. Problem is: I dont know how to implement a background worker. I know Sync Toy does what I am trying to do, but I have to submit the source code, and it needs to be hard coded for some things. So its a "no deal."
All clients on the network is Win7, 100/1000Mb LAN, and decent specs.
Requirements:
-One-Way Sync only, but from three different sources on the LAN...UNC network paths. Destination is one or more plugged in USB hard drives (spinning, not flash).
-Overwrite destination on conflict.
-Progress Bar, works now, but only for one of the syncs, and locks up upon sync start.
-Would love to add a semi-accurate remaining ETA, either time/files/bytes/etc.
-Good coding practice, but so far not my strong suit, but Im working on it.
-Cancel ability (hence the background worker)
I have the form and most of the code in a semi-working fashion, I didnt want to post it all here, but here is the sync class I am working from. Any help would be appreciated. I can share via Team Foundation, or send the entire solution to get a better picture of how Ive messed it up. Really just hoping to get some ideas on how to streamline and get it to a usable fashion. Better Multi-threading would be cool, making the drop-downs for source/dest work better can happen later, and some persistent user settings would be awesome, but not rush.
So far, I love the way sync framework compares files, but I get the feeling Im not doing the preview mode for progress bar and actual sync properly.
Obviously, this isnt a use for any kind of profit, but if someone is willing to help me get to a good point, id be happy to send you an American Flag flown over the skies of Afghanistan or something cool like that!using System;
using Microsoft.Synchronization.Files;
using Microsoft.Synchronization;
namespace SyncFramework1
{
/// <summary>
/// Perform an optimised file sync
/// </summary>
public class OptimisedSyncHelper
{
#region Events and Delegates
public event EventHandler<RequiredChangeInformationEventArgs> RequiredChangeInformation;
public event EventHandler<DetectingChangesEventArgs> DetectingChanges;
public event EventHandler<AppliedChangeEventArgs> AppliedChange;
public event EventHandler<SkippedChangeEventArgs> SkippedChange;
#endregion
#region Public Implementation
/// <summary>
/// Perform the synchronisation
/// </summary>
/// <param name="sourceFolder </param>
/// <param name="targetFolder </param>
/// <param name="provideProgressInformation </param>
/// <param name="uploadStatistics </param>
/// <param name="downloadStatistics </param>
public void PerformSynchronisation(string sourceFolder, string targetFolder, out SyncOperationStatistics uploadStatistics, out SyncOperationStatistics downloadStatistics)
{
// Set options for the sync operation
FileSyncOptions options = FileSyncOptions.ExplicitDetectChanges | FileSyncOptions.RecycleDeletedFiles | FileSyncOptions.RecyclePreviousFileOnUpdates | FileSyncOptions.RecycleConflictLoserFiles;
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk"); // Exclude all *.lnk files
// Explicitly detect changes on both replicas upfront, to avoid two change detection passes for the two-way sync
DetectChangesOnFileSystemReplica(sourceFolder, filter, options);
DetectChangesOnFileSystemReplica(targetFolder, filter, options);
// Sync in both directions
uploadStatistics = SyncFileSystemReplicasOneWay(sourceFolder, targetFolder, filter, options, false);
downloadStatistics = SyncFileSystemReplicasOneWay(targetFolder, sourceFolder, filter, options, false);
// If we want preview/progress information - pass to the consumer
int totalChangesRequired = uploadStatistics.UploadChangesTotal + uploadStatistics.DownloadChangesTotal + downloadStatistics.UploadChangesTotal + downloadStatistics.DownloadChangesTotal;
OnRequiredChangeInformation(totalChangesRequired);
uploadStatistics = SyncFileSystemReplicasOneWay(sourceFolder, targetFolder, filter, options, false);
downloadStatistics = SyncFileSystemReplicasOneWay(targetFolder, sourceFolder, filter, options, false);
}
#endregion
#region Event Wrappers
/// <summary>
/// Raise an event if necessary indicating the number of changes required.
/// </summary>
/// <param name="totalChangesRequired </param>
private void OnRequiredChangeInformation(int totalChangesRequired)
{
if (RequiredChangeInformation != null)
{
RequiredChangeInformation(this, new RequiredChangeInformationEventArgs(totalChangesRequired));
}
}
/// <summary>
/// Raise an event if necessary indicating that a detecting change operation is occuring
/// </summary>
/// <param name="sender </param>
/// <param name="e </param>
private void OnDetectingChanges(object sender, DetectingChangesEventArgs e)
{
if (DetectingChanges != null)
{
DetectingChanges(sender, e);
}
}
/// <summary>
/// Report that an operation has been performed
/// </summary>
/// <param name="sender </param>
/// <param name="args </param>
private void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
if (AppliedChange != null)
{
AppliedChange(this, args);
}
}
/// <summary>
/// Report that an operation was skipped.
/// </summary>
/// <param name="sender </param>
/// <param name="args </param>
private void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
if (SkippedChange != null)
{
SkippedChange(this, args);
}
}
#endregion
#region Private Implementation
/// <summary>
/// Perform a DetectChange operation on a FileSyncProvider.
/// </summary>
/// <param name="replicaRootPath </param>
/// <param name="filter </param>
/// <param name="options </param>
private void DetectChangesOnFileSystemReplica(string replicaRootPath, FileSyncScopeFilter filter, FileSyncOptions options)
{
using (FileSyncProvider provider = new FileSyncProvider(replicaRootPath, filter, options))
{
provider.DetectingChanges += new EventHandler<DetectingChangesEventArgs>(OnDetectingChanges);
provider.DetectChanges();
}
}
/// <summary>
/// Perform a 1 way sync
/// </summary>
/// <param name="sourceFolder </param>
/// <param name="targetFolder </param>
/// <param name="filter </param>
/// <param name="options </param>
/// <param name="preview </param>
/// <returns></returns>
private SyncOperationStatistics SyncFileSystemReplicasOneWay(string sourceFolder, string targetFolder, FileSyncScopeFilter filter, FileSyncOptions options, bool preview)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider targetProvider = null;
try
{
sourceProvider = new FileSyncProvider(sourceFolder, filter, options);
targetProvider = new FileSyncProvider(targetFolder, filter, options);
sourceProvider.PreviewMode = preview;
targetProvider.PreviewMode = preview;
targetProvider.AppliedChange += new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
targetProvider.SkippedChange += new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = targetProvider;
agent.Direction = SyncDirectionOrder.Upload; // Sync source to destination
return agent.Synchronize();
}
finally
{
// Release resources
if (sourceProvider != null)
{
sourceProvider.Dispose();
}
if (targetProvider != null)
{
targetProvider.Dispose();
}
}
}
#endregion
}
}
View the full article