BackgroundWorker Sync Framework C#

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
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
 
This was my original post on the MSDN Forums...anyone willing to work with me to try and get this moved along. Ive got a good idea of what I am trying to accomplish for 1 source, but I am trying to port it to three separate sources, and use an async method to avoid locking up the UI, and now Id like to do all three sync at once in a parallel fashion.

Feel free to message with suggestions, ideas, or to get a better idea (I am not c# experienced at all, but doing okay to get started from books)

P.S. NOT for school or for PROFIT
 
Back
Top