Update issue #185

Status: Fixed
The code to support this was already in place, but did
not work because Application.Exit() had been invoked,
making all messageboxes return Cancel without showing.

I also improved the logic a bit so a cancel does
not invoke the cleanup afterwards, making the exit
procedure faster.

I also added checks for the stop command to the
code that fetches the signature files, to make
the application respond faster to the stop command.

git-svn-id: https://duplicati.googlecode.com/svn/trunk@490 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
kenneth.skovhede@gmail.com
2010-09-01 21:04:18 +00:00
parent 85dfb95d79
commit 79fdce5ca6
9 changed files with 132 additions and 47 deletions
+7 -1
View File
@@ -59,6 +59,7 @@ namespace Duplicati.GUI
string destination = task.GetConfiguration(options);
string results = "";
bool isAbortException = false;
try
{
@@ -224,7 +225,12 @@ namespace Duplicati.GUI
{
//TODO: Extract ex.Message and save it in seperate field in the database
if (ex is System.Threading.ThreadAbortException)
{
isAbortException = true;
System.Threading.Thread.ResetAbort();
}
else if (ex is Library.Main.LiveControl.ExecutionStoppedException)
isAbortException = true;
while (ex is System.Reflection.TargetInvocationException && ex.InnerException != null)
ex = ex.InnerException;
@@ -240,7 +246,7 @@ namespace Duplicati.GUI
try
{
if (task.TaskType == DuplicityTaskType.FullBackup || task.TaskType == DuplicityTaskType.IncrementalBackup)
if (!isAbortException && (task.TaskType == DuplicityTaskType.FullBackup || task.TaskType == DuplicityTaskType.IncrementalBackup))
{
if (task.Schedule.Task.KeepFull > 0)
{
+65
View File
@@ -179,6 +179,15 @@ namespace Duplicati.GUI
Program.LiveControl.Pause();
Program.Runner.Stop();
TrayIcon.Visible = false;
if (StatusDialog != null && StatusDialog.Visible)
StatusDialog.Close();
if (WizardDialog != null && WizardDialog.Visible)
WizardDialog.Close();
EnsureBackupIsTerminated();
Application.Exit();
}
@@ -305,5 +314,61 @@ namespace Duplicati.GUI
return false;
}
private void EnsureBackupIsTerminated()
{
if (Program.Runner != null && Program.WorkThread != null && Program.WorkThread.Active)
{
//Make sure no new items can enter the queue
if (Program.Scheduler != null)
Program.Scheduler.Terminate(true);
//We want no new items to enter the queue
Program.WorkThread.Terminate(false);
Program.Runner.Pause();
if (!Program.Runner.IsStopRequested)
Program.Runner.Stop();
//Wait 15 seconds to see if the stop works
for (int i = 0; i < 15; i++)
{
Program.WorkThread.Join(1000);
Application.DoEvents();
if (!Program.WorkThread.Active)
break;
}
while (Program.WorkThread.Active)
{
//Ask the user if we should abort
if (MessageBox.Show(Strings.Program.TerminateForExitQuestion, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
//Abort the thread
Program.Runner.Terminate();
//Give last 5 second chance to write the remaining data
int i = 5;
while (i > 0 && !Program.WorkThread.Join(1000))
{
//The Join call blocks the main thread, so let pending events through
Application.DoEvents();
i--;
}
break;
}
//Wait 18 * 10 seconds = 3 minutes before asking again
for (int i = 0; i < 18; i++)
{
Program.WorkThread.Join(1000 * 10);
Application.DoEvents();
if (!Program.WorkThread.Active)
break;
}
}
}
}
}
}
-32
View File
@@ -207,38 +207,6 @@ namespace Duplicati.GUI
MessageBox.Show(string.Format(Strings.Program.SeriousError, ex.ToString()), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (Runner != null && WorkThread != null && WorkThread.Active)
{
Runner.Pause();
if (!Runner.IsStopRequested)
Runner.Stop();
//Wait 10 seconds to see if the stop works
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(1000);
if (!WorkThread.Active)
break;
}
while (WorkThread.Active)
{
if (MessageBox.Show(Strings.Program.TerminateForExitQuestion, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
Runner.Terminate();
System.Threading.Thread.Sleep(500);
break;
}
//Wait 18 * 10 seconds = 3 minutes before asking again
for (int i = 0; i < 18; i++)
{
System.Threading.Thread.Sleep(1000 * 10);
if (!WorkThread.Active)
break;
}
}
}
if (Scheduler != null)
Scheduler.Terminate(true);
+5
View File
@@ -273,6 +273,11 @@ namespace Duplicati.GUI
(m_form as Form).ShowDialog();
}
public void Close()
{
if ((m_form as Form).Visible)
(m_form as Form).Close();
}
private bool AskToResumeIfPaused()
{
+12
View File
@@ -295,5 +295,17 @@ namespace Duplicati.GUI
m_state = RunState.Paused;
m_event.Set();
}
/// <summary>
/// Waits the specified number of milliseconds for the thread to terminate
/// </summary>
/// <param name="millisecondTimeout">The number of milliseconds to wait</param>
/// <returns>True if the thread is terminated, false if a timeout occured</returns>
public bool Join(int millisecondTimeout)
{
if (m_thread != null)
return m_thread.Join(millisecondTimeout);
return true;
}
}
}
+17 -3
View File
@@ -574,6 +574,11 @@ namespace Duplicati.Library.Main
m_statistics.NumberOfRemoteCalls++;
return m_backend.List();
}
catch (System.Threading.ThreadAbortException tex)
{
lastEx = tex;
retries = 0;
}
catch (Exception ex)
{
lastEx = ex;
@@ -601,6 +606,11 @@ namespace Duplicati.Library.Main
m_backend.Delete(remote.Filename);
lastEx = null;
}
catch (System.Threading.ThreadAbortException tex)
{
lastEx = tex;
retries = 0;
}
catch (Exception ex)
{
lastEx = ex;
@@ -682,7 +692,7 @@ namespace Duplicati.Library.Main
{
try
{
using(Library.Interface.IEncryption enc = DynamicLoader.EncryptionLoader.GetModule(remote.EncryptionMode, m_options.Passphrase, m_options.RawOptions))
using (Library.Interface.IEncryption enc = DynamicLoader.EncryptionLoader.GetModule(remote.EncryptionMode, m_options.Passphrase, m_options.RawOptions))
enc.Decrypt(tempfile, filename);
}
catch (Exception ex)
@@ -724,6 +734,11 @@ namespace Duplicati.Library.Main
}
}
}
catch (System.Threading.ThreadAbortException tex)
{
lastEx = tex;
retries = 0;
}
catch (Exception ex)
{
lastEx = ex;
@@ -821,9 +836,8 @@ namespace Duplicati.Library.Main
}
catch (System.Threading.ThreadAbortException tex)
{
//Do not retry after we are aborted
lastEx = tex;
break;
retries = 0;
}
catch (Exception ex)
{
+7 -1
View File
@@ -197,8 +197,12 @@ namespace Duplicati.Library.Main
entries.Add(backupsets[backupsets.Count - 1]);
entries.AddRange(backupsets[backupsets.Count - 1].Incrementals);
//Check before we start the download
CheckLiveControl();
patches = FindPatches(backend, entries, tempfolder);
//Check before we start the download
CheckLiveControl();
Manifestfile latest = GetManifest(backend, backupsets[0]);
//Manifest version 1 does not support multiple folders
@@ -1136,7 +1140,6 @@ namespace Duplicati.Library.Main
{
m_progress += unitCost;
OperationProgress(this, DuplicatiOperation.Backup, (int)(m_progress * 100), -1, string.Format(Strings.Interface.StatusReadingManifest, be.Time.ToShortDateString() + " " + be.Time.ToShortTimeString()), "");
Manifestfile manifest = GetManifest(backend, be);
@@ -1157,6 +1160,9 @@ namespace Duplicati.Library.Main
string filename = System.IO.Path.Combine(tempfolder, "patch-" + patches.Count.ToString() + ".zip");
//Check just before we download stuff
CheckLiveControl();
using (new Logging.Timer("Get " + bes.Key.Filename))
backend.Get(bes.Key, filename, manifest.SignatureHashes == null ? null : manifest.SignatureHashes[bes.Key.Volumenumber - 1]);
@@ -23,7 +23,7 @@ using System.Text;
namespace Duplicati.Library.Main.LiveControl
{
class ExecutionStoppedException : Exception
public class ExecutionStoppedException : Exception
{
public ExecutionStoppedException()
: base(Strings.ExecutionStoppedException.DefaultMessage)
+18 -9
View File
@@ -1558,17 +1558,26 @@ namespace Duplicati.Library.Main.RSync
{
BackupStatistics bs = m_stat as BackupStatistics;
bs.DeletedFiles = m_deletedfiles.Count;
bs.DeletedFolders = m_deletedfolders.Count;
bs.ModifiedFiles = m_diffedfiles;
bs.AddedFiles = m_addedfiles;
bs.ExaminedFiles = m_examinedfiles;
bs.SizeOfModifiedFiles = m_diffedfilessize;
bs.SizeOfAddedFiles = m_addedfilessize;
bs.SizeOfExaminedFiles = m_examinedfilesize;
if (m_deletedfiles != null)
bs.DeletedFiles = m_deletedfiles.Count;
if (m_deletedfolders != null)
bs.DeletedFolders = m_deletedfolders.Count;
if (m_diffedfiles != null)
bs.ModifiedFiles = m_diffedfiles;
if (m_addedfiles != null)
bs.AddedFiles = m_addedfiles;
if (m_examinedfiles != null)
bs.ExaminedFiles = m_examinedfiles;
if (m_diffedfilessize != null)
bs.SizeOfModifiedFiles = m_diffedfilessize;
if (m_addedfilessize != null)
bs.SizeOfAddedFiles = m_addedfilessize;
if (m_examinedfilesize != null)
bs.SizeOfExaminedFiles = m_examinedfilesize;
if (m_unproccesed != null && m_unproccesed.Files != null)
bs.UnprocessedFiles = m_unproccesed.Files.Count;
bs.AddedFolders = m_newfolders.Count;
if (m_newfolders != null)
bs.AddedFolders = m_newfolders.Count;
}
if (m_snapshot != null)