Ejemplo n.º 1
0
 public download_m3u8File_parts_parallel_params_t(DownloadPartsAndSaveInputParams ip) : this()
 {
     mc                     = ip.mc;
     m3u8File               = ip.m3u8File;
     cts                    = ip.Cts;
     requestStepAction      = ip.RequestStepAction;
     responseStepAction     = ip.ResponseStepAction;
     maxDegreeOfParallelism = ip.MaxDegreeOfParallelism;
 }
Ejemplo n.º 2
0
 public download_m3u8File_parts_parallel_params_t(DownloadPartsAndSaveInputParams ip) : this()
 {
     mc                     = ip.mc;
     m3u8File               = ip.m3u8File;
     cts                    = ip.Cts;
     waitIfPausedEvent      = ip.WaitIfPausedEvent;
     waitingIfPaused        = ip.WaitingIfPaused;
     requestStepAction      = ip.RequestStepAction;
     responseStepAction     = ip.ResponseStepAction;
     maxDegreeOfParallelism = ip.MaxDegreeOfParallelism;
     useCrossAppInstanceDegreeOfParallelism = ip.UseCrossAppInstanceDegreeOfParallelism;
 }
Ejemplo n.º 3
0
        private static IEnumerable <m3u8_part_ts> download_m3u8File_parts_parallel(DownloadPartsAndSaveInputParams ip)
        {
            var ct          = (ip.Cts?.Token).GetValueOrDefault(CancellationToken.None);
            var m3u8File    = ip.m3u8File;
            var baseAddress = m3u8File.BaseAddress;
            var totalPatrs  = m3u8File.Parts.Count;
            var successReceivedPartCount = 0;
            var failedReceivedPartCount  = 0;

            ip.ResponseStepAction?.Invoke(new ResponseStepActionParams(totalPatrs));

            var expectedPartNumber = m3u8File.Parts.FirstOrDefault().OrderNumber;
            var maxPartNumber      = m3u8File.Parts.LastOrDefault().OrderNumber;
            var sourceQueue        = new Queue <m3u8_part_ts>(m3u8File.Parts);
            var downloadPartsSet   = new SortedSet <m3u8_part_ts>(default(m3u8_part_ts.comparer));

            using (var innerCts = new CancellationTokenSource())
                using (var joinedCts = CancellationTokenSource.CreateLinkedTokenSource(ct, innerCts.Token))
                    using (var canExtractPartEvent = new AutoResetEvent(false))
                    {
                        //-1-//
                        var task_download = Task.Run(() =>
                        {
                            for (var n = 1; sourceQueue.Count != 0; n++)
                            {
                                #region [.check 'waitIfPausedEvent'.]
                                if (!ip.WaitIfPausedEvent.IsSet)
                                {
                                    ip.WaitingIfPaused?.Invoke();
                                    ip.WaitIfPausedEvent.Wait(joinedCts.Token);
                                }
                                #endregion

                                ip.DownloadThreadsSemaphore.Wait(/*ct*/ joinedCts.Token);
                                var part = sourceQueue.Dequeue();

                                var rq = RequestStepActionParams.CreateSuccess(totalPatrs, n, part);
                                ip.RequestStepAction?.Invoke(rq);

                                ip.mc.DownloadPart(part, baseAddress, /*ct*/ joinedCts.Token)
                                .ContinueWith(continuationTask =>
                                {
                                    var rsp = new ResponseStepActionParams(totalPatrs);

                                    if (continuationTask.IsFaulted)
                                    {
                                        Interlocked.Increment(ref expectedPartNumber);

                                        part.SetError(continuationTask.Exception);

                                        rsp.SuccessReceivedPartCount = successReceivedPartCount;
                                        rsp.FailedReceivedPartCount  = Interlocked.Increment(ref failedReceivedPartCount);
                                        rsp.Part = part;

                                        ip.ResponseStepAction?.Invoke(rsp);

                                        innerCts.Cancel();
                                    }
                                    else if (!continuationTask.IsCanceled)
                                    {
                                        var downloadPart = continuationTask.Result;
                                        if (downloadPart.Error != null)
                                        {
                                            rsp.SuccessReceivedPartCount = successReceivedPartCount;
                                            rsp.FailedReceivedPartCount  = Interlocked.Increment(ref failedReceivedPartCount);
                                        }
                                        else
                                        {
                                            rsp.SuccessReceivedPartCount = Interlocked.Increment(ref successReceivedPartCount);
                                            rsp.FailedReceivedPartCount  = failedReceivedPartCount;
                                            rsp.BytesLength = downloadPart.Bytes.Length;
                                        }
                                        rsp.Part = downloadPart;
                                        ip.ResponseStepAction?.Invoke(rsp);

                                        lock ( downloadPartsSet )
                                        {
                                            downloadPartsSet.Add(downloadPart);
                                            canExtractPartEvent.Set();
                                        }
                                    }
                                }, /*ct*/ joinedCts.Token);
                            }
                        }, /*ct*/ joinedCts.Token);

                        //-2-//
                        for (var localReadyParts = new Queue <m3u8_part_ts>(Math.Min(0x1000, ip.MaxDegreeOfParallelism));
                             expectedPartNumber <= maxPartNumber;)
                        {
                            var idx = WaitHandle.WaitAny(new[] { canExtractPartEvent /*0*/, /*ct*/ joinedCts.Token.WaitHandle /*1*/, });
                            if (idx == 1) //[ct.IsCancellationRequested := 1]
                            {
                                break;
                            }
                            if (idx != 0) //[canExtractPartEvent := 0]
                            {
                                continue;
                            }

                            lock ( downloadPartsSet )
                            {
                                for ( ; downloadPartsSet.Count != 0;)
                                {
                                    var min_part = downloadPartsSet.Min;
                                    if (expectedPartNumber == min_part.OrderNumber)
                                    {
                                        downloadPartsSet.Remove(min_part);

                                        Interlocked.Increment(ref expectedPartNumber);

                                        ip.DownloadThreadsSemaphore.Release();

                                        localReadyParts.Enqueue(min_part);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }

                            for ( ; localReadyParts.Count != 0;)
                            {
                                var part = localReadyParts.Dequeue();
                                yield return(part);
                            }
                        }

                        //-3.0-//
                        if (innerCts.IsCancellationRequested)
                        {
                            throw (new m3u8_Exception("Canceled after part download error"));
                        }

                        //-3-//
                        task_download.Wait();
                    }

            //-4-//
            ct.ThrowIfCancellationRequested();
        }