/// <summary> /// Starts the download task. /// </summary> public void StartDownload() { RemoteFileInfo remoteFileInfo = null; try { ChangeState(DownloadTaskState.Preparing); m_StartDate = DateTime.Now; INetworkProtocolProvider networkProtocolProvider = m_NetworkProtocolProviderFactory.CreateProvider(m_File.Uri); remoteFileInfo = networkProtocolProvider.GetRemoteFileInfo(m_File); remoteFileInfo.FileName = m_File.FileName; m_FileSize = remoteFileInfo.FileSize; m_IsResumable = remoteFileInfo.AcceptRanges; DownloadSegmentPositions[] segmentPositionInfos; if (remoteFileInfo.AcceptRanges) { segmentPositionInfos = m_DownloadSegmentCalculator.Calculate(m_Settings.MinimumSegmentSize, m_Settings.MaximumSegmentCount, m_File.SegmentCount, remoteFileInfo.FileSize); } else { segmentPositionInfos = new[] { new DownloadSegmentPositions(0, remoteFileInfo.FileSize - 1) }; } using (Stream stream = m_DownloadStreamManager.CreateStream(remoteFileInfo)) { SegmentWriter segmentWriter = new SegmentWriter(stream); SegmentDownloadTasks = new SegmentDownloadTaskCollection(segmentPositionInfos.Length); for (int i = 0; i < segmentPositionInfos.Length; i++) { DownloadSegmentPositions segmentPosition = segmentPositionInfos[i]; SegmentDownloadTasks.Add(new DoubleBufferSegmentDownloadTask(m_Settings.DownloadBufferSize, new SegmentDownloader(m_File, networkProtocolProvider, segmentPosition, new SegmentDownloadRateCalculator(segmentPosition.StartPosition)), segmentWriter)); } SegmentDownloadManager segmentDownloadManager = new SegmentDownloadManager(SegmentDownloadTasks); segmentDownloadManager.Start(); ChangeState(DownloadTaskState.Working); segmentDownloadManager.Finish(true); ChangeState(DownloadTaskState.Ended); m_EventManager.EventPublisher.Publish(new DownloadTaskFinishedEventMessage(this, stream, remoteFileInfo)); } } catch (Exception ex) { if (m_RetryCount < m_Settings.MaximumRetries) { m_RetryCount++; StartDownload(); } else { m_LastException = ex; ChangeState(DownloadTaskState.EndedWithError); m_EventManager.EventPublisher.Publish(new DownloadTaskFinishedEventMessage(this, null, remoteFileInfo)); } } }