public override void Run() { long x; string id; IFile destTemp; ITempIdentityFileService destTempService; IFile dest; Stream srcStream = null, destStream = null; IFileHashingService hasher; string sourceHash, destTempHash; try { lock (this.SyncLock) { m_TaskThread = Thread.CurrentThread; if (m_TransferState != TransferState.NotStarted) { throw new InvalidOperationException(); } SetTransferState(TransferState.Preparing); ProcessTaskStateRequest(); } id = m_Source.Address.Uri + m_Source.Length.ToString() + (m_Source.Attributes.CreationTime ?? DateTime.MinValue).ToBinary().ToString(); destTempService = (ITempIdentityFileService)m_Destination.GetService(new TempIdentityFileServiceType(id)); destTemp = destTempService.GetTempFile(); for (;;) { try { x = destTemp.Length; } catch (FileNotFoundException) { x = 0; } dest = m_Destination.ParentDirectory.ResolveFile("$TMP_" + m_Destination.Address.Name + "_" + Guid.NewGuid().ToString("N")); try { if (x == m_Source.Length) { try { if (m_Source.IdenticalTo(destTemp, FileComparingFlags.CompareContents)) { SetTransferState(TransferState.Copying); ProcessTaskStateRequest(); m_Progress.RaiseValueChanged(m_Progress.CurrentValue, 0); destTemp.MoveTo(dest, true); if (!m_Source.IdenticalTo(dest, FileComparingFlags.CompareContents)) { continue; } dest.RenameTo(m_Destination.Address.NameAndQuery, true); m_BytesTransferred = m_Destination.Length; m_Progress.RaiseValueChanged(m_Progress.CurrentValue, m_BytesTransferred); SetTransferState(TransferState.Finished); ProcessTaskStateRequest(); return; } } catch (IOException) { } } srcStream = m_Source.GetContent().GetInputStream(FileShare.Read); if (!srcStream.CanSeek) { destStream = destTemp.GetContent().GetOutputStream(FileMode.Create, FileShare.Read); } else { destStream = destTemp.GetContent().GetOutputStream(FileMode.Append, FileShare.Read); SetTransferState(TransferState.Comparing); ProcessTaskStateRequest(); hasher = (IFileHashingService)m_Source.GetService(new FileHashingServiceType("md5")); sourceHash = hasher.ComputeHash(0, destStream.Length).TextValue; hasher = (IFileHashingService)destTemp.GetService(new FileHashingServiceType("md5")); destTempHash = hasher.ComputeHash().TextValue; if (sourceHash != destTempHash) { destStream.Close(); destStream = destTemp.GetContent().GetOutputStream(FileMode.Create, FileShare.Read); } else { m_Offset = destStream.Length; if (m_Offset > 0) { srcStream = new PartialStream(srcStream, m_Offset); } } } m_Progress.RaiseValueChanged(0, m_Offset); ProcessTaskStateRequest(); m_Pump = new StreamPump(srcStream, destStream, true, false, m_ServiceType.BufferSize); m_Pump.TaskStateChanged += new TaskEventHandler(Pump_TaskStateChanged); SetTransferState(TransferState.Transferring); ProcessTaskStateRequest(); m_Pump.Run(); if (m_Pump.TaskState == TaskState.Stopped) { throw new StopRequestedException(); } SetTransferState(TransferState.Copying); ProcessTaskStateRequest(); } finally { if (srcStream != null) { Routines.IgnoreExceptions(delegate { srcStream.Close(); }); } if (destStream != null) { Routines.IgnoreExceptions(delegate { destStream.Close(); }); } } break; } SetTransferState(TransferState.Tidying); destTemp.MoveTo(dest, true); /// /// Aquire an UpdateContext for the attributes /// so that all updates to the attributes are /// commited in a single operation /// using (dest.Attributes.AquireUpdateContext()) { foreach (string s in this.m_ServiceType.AttributesToTransfer) { dest.Attributes[s] = m_Source.Attributes[s]; } } dest.RenameTo(m_Destination.Address.Name, true); SetTransferState(TransferState.Finished); } finally { if (m_TransferState != TransferState.Stopped) { SetTransferState(TransferState.Finished); } } }