locked
Cancel a File Synchronization RRS feed

  • Question

  • I have a File Syncronization occuring within a Background Worker process.  How do I implement a cancel on the file synchronization if a user presses a Cancel button?

    Thanks,

    -saige-
    Tuesday, May 19, 2009 9:56 PM

Answers

  • Hi -

    This counds correct because your programming model is for your background worker to check status ( not for it to be notified). And checking in the eventing code is perfectly acceptable.

    Thanks
    Deepa
    Deepa ( Microsoft Sync Framework)
    Tuesday, May 26, 2009 11:01 PM
    Answerer

All replies

  • Hi -

    Looking through the msdn pages I see -
    http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx

    Your worker thread is expected to check periodically and call Cancel on the SyncSession.

    Thanks
    Deepa
    Deepa ( Microsoft Sync Framework)
    Thursday, May 21, 2009 1:49 AM
    Answerer
  • I already knew about the backgroundworker.cancelasync method.  I had already implemented it, but the problem that I ran into was how to let the synchronization method running inside the background worker process know that a cancel had been requested.  Currently here is the method that I use to do this:

    Global Variable

    'In Main Form
    Public Class frmMain
    	'Global Variables
    	Dim agent As SyncOrchestrator = New SyncOrchestrator
    	Dim isCanceled As Boolean = False
    
    'In Progress Form
    Private Sub btnAbortSync_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAbortSync.Click
    	If frmMain.btnQuit.Enabled = True Then
    		strAbortSync = frmMain.lblStripStatus.Text
    
    		' Cancel the asynchronous operation.
    		frmMain.backgroundWorker.CancelAsync()
    	End If
    End Sub
    
    ' Back in Main Form
    Public Sub OnAppliedChange(ByVal sender As Object, ByVal args As AppliedChangeEventArgs)
    	If backgroundWorker.CancellationPending Then
    		isCanceled = True
    		With agent
    			Select Case .State()
    				Case SyncOrchestratorState.Ready
    				Case SyncOrchestratorState.Downloading
    				Case SyncOrchestratorState.Uploading
    				Case SyncOrchestratorState.UploadingAndDownloading
    					strTemp += "Synchronization Cancel requested during synchronization on file --- " _
    					 & args.NewFilePath _
    					 & vbCrLf
    					agent.Cancel()
    				Case SyncOrchestratorState.Canceled
    					strTemp += "Synchronization Completed Cancelling --- " _
    					 & vbCrLf
    				Case SyncOrchestratorState.Canceling
    					strTemp += "Synchronization Cancelling on file --- " _
    					 & args.NewFilePath _
    					 & vbCrLf
    					agent.Cancel()
    			End Select
    		End With
    	Else
    And so forth and so on...  Basically to explain it, I globalized the creation of the SyncOrchestrator and a boolean value named isCanceled.  When someone clicks on the cancel button in the progress form, the Background Worker Process is placed into a state of CancellationPending.

    Since the syncrhonization could already have been started I had to add into the Event Handlers [AppliedChange, SkippedChange, DetectingChanges and ApplyingChange], the code to test if the Background Worker Process is in a state of CancellationPending.  If it is then the state of the SyncOrchstrator is then checked and appropriate action is taken.

    Does anyone have a more elegant or efficient solution?

    Thanks,

    -saige-
    Saturday, May 23, 2009 10:10 PM
  • Hi, Saige45.
    A couple of thoughts on your problem:

    1. Since you globalized the Orchestrator, you could probably call Cancel() directly on the Orchestrator. You could also use the boolean flag to make sure you don't call Cancel()
        twice (another aproach is to simply disable the Cancel button once it was clicked).
    2. About logging - don't rely on the fact that if you call Orchestrator.Cancel() while processing fileX, fileX will not be processed. Having logging messages in the Event Handlers
        will give you a more real picture on which changes have been applied and which ones have not been applied.
    3. Having one single place of cancellation would give you easier debugging of any issues which might occur later while maintaining your app.

    Hope this helps.
    Adrian

    Tuesday, May 26, 2009 10:59 PM
  • Hi -

    This counds correct because your programming model is for your background worker to check status ( not for it to be notified). And checking in the eventing code is perfectly acceptable.

    Thanks
    Deepa
    Deepa ( Microsoft Sync Framework)
    Tuesday, May 26, 2009 11:01 PM
    Answerer
  • Good thoughts.  However, I already considered the canceling while a file was in transit which is why I do the initial check to see if the background worker is pending cancellation.  After that the isCancel is used as a controlling/finishing variable.  Logic here is that the thread for the sync orchestrator dies when the background worker dies.  Therefore, to determine if a cancel call was placed I have a global boolean variable to tell me this.

    Thanks for the other tips as well.

    -saige-
    Thursday, May 28, 2009 2:23 AM
  • If I understand the model correctly, the event handler fires when the event occurs???  In other words, when a change is applied, the change (Create, Delete, Rename or Overwrite) has already occurred??? or is occurring???

    -saige-
    Thursday, May 28, 2009 2:26 AM