示例#1
0
文件: Channel.cs 项目: Danstahr/cocol
        /// <summary>
        /// Helper method for dequeueing write requests after space has been allocated in the writer queue
        /// </summary>
        /// <param name="isLocked"><c>True</c> if we are already holding the lock, <c>false</c> otherwise</param>
        private async Task ProcessWriteQueueBufferAfterReadAsync(bool isLocked)
        {
            using (isLocked ? default(AsyncLock.Releaser) : await m_asynclock.LockAsync())
            {
                // If there is now a buffer slot in the queue, trigger a callback to a waiting item
                while (m_retireCount < 0 && m_bufferSize > 0 && m_writerQueue.Count >= m_bufferSize)
                {
                    var nextItem = m_writerQueue[m_bufferSize - 1];

                    if (nextItem.Offer == null || await nextItem.Offer.OfferAsync(this))
                    {
                        if (nextItem.Offer != null)
                        {
                            await nextItem.Offer.CommitAsync(this);
                        }

                        if (nextItem.Source != null)
                        {
                            nextItem.Source.SetResult(true);
                        }

                        // Now that the transaction has completed for the writer, record it as waiting forever
                        m_writerQueue[m_bufferSize - 1] = new WriterEntry(null, null, Timeout.InfiniteDateTime, nextItem.Value);

                        // We can have at most one, since we process at most one read
                        break;
                    }
                    else
                    {
                        m_writerQueue.RemoveAt(m_bufferSize - 1);
                    }
                }
            }
        }
        public Stream CreateFile(string file, CompressionHint hint, DateTime lastWrite)
        {
            if (string.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (m_writer == null)
            {
                throw new InvalidOperationException(Strings.SevenZipCompression.NoWriterError);
            }

            var entry = new WriterEntry(file, lastWrite);

            if (hint != CompressionHint.Noncompressible)
            {
                if (m_lzma2Encoder == null)
                {
                    if (m_lowOverheadMode)
                    {
                        m_lzma2Encoder = new ManagedLzma.LZMA.Master.SevenZip.ArchiveWriter.LzmaEncoder();
                    }
                    else
                    {
                        m_lzma2Encoder = new ManagedLzma.LZMA.Master.SevenZip.ArchiveWriter.Lzma2Encoder(m_threadCount, m_encoderProps);
                    }

                    m_lzma2Encoder.OnOutputThresholdReached += mLzma2Encoder_OnOutputThresholdReached;
                    m_lzma2Encoder.SetOutputThreshold(kStreamThreshold);
                }

                return(m_lzma2Encoder.BeginWriteFile(entry));
            }
            else
            {
                if (m_copyEncoder == null)
                {
                    m_copyEncoder = new ManagedLzma.LZMA.Master.SevenZip.ArchiveWriter.PlainEncoder();
                }

                if (m_lzma2Encoder != null && m_lzma2Encoder == m_writer.CurrentEncoder)
                {
                    m_lzma2Encoder.SetOutputThreshold(kStreamThreshold); // rearm threshold so we can switch back
                }
                if (m_writer.CurrentEncoder != m_copyEncoder)
                {
                    m_writer.ConnectEncoder(m_copyEncoder);
                }

                return(m_copyEncoder.BeginWriteFile(entry));
            }
        }
示例#3
0
文件: Channel.cs 项目: Danstahr/cocol
        /// <summary>
        /// Offers a transaction to the write end
        /// </summary>
        /// <param name="wr">The writer entry.</param>
        protected async Task <bool> Offer(WriterEntry wr)
        {
            Exception tex    = null;
            bool      accept = false;

            System.Diagnostics.Debug.Assert(wr.Source == m_writerQueue[0].Source);

            try
            {
                accept = (wr.Source == null || wr.Source.Task.Status == TaskStatus.WaitingForActivation) && (wr.Offer == null || await wr.Offer.OfferAsync(this));
            }
            catch (Exception ex)
            {
                tex = ex;                 // Workaround to support C# 5.0, with no await in catch clause
            }

            if (tex != null)
            {
                wr.Source.TrySetException(tex);
                m_writerQueue.RemoveAt(0);

                return(false);
            }

            if (!accept)
            {
                if (wr.Source != null)
                {
                    wr.Source.TrySetCanceled();
                }
                m_writerQueue.RemoveAt(0);

                return(false);
            }

            return(true);
        }
示例#4
0
        /// <summary>
        /// Initializes the bindings for the page controls.
        /// </summary>
        void InitBindings()
        {
            CoverImage.SetBinding(Image.SourceProperty, "ImageSmall");

            SeriesNoEntry.SetBinding(Entry.TextProperty,
                                     new Binding("SeriesNumber")
            {
                Mode = BindingMode.TwoWay
            });
            SeriesNameEntry.SetBinding(Entry.TextProperty,
                                       new Binding("SeriesName")
            {
                Mode = BindingMode.TwoWay
            });
            WriterEntry.SetBinding(Entry.TextProperty,
                                   new Binding("Writer")
            {
                Mode = BindingMode.TwoWay
            });
            PencillerEntry.SetBinding(Entry.TextProperty,
                                      new Binding("Penciller")
            {
                Mode = BindingMode.TwoWay
            });
            InkerEntry.SetBinding(Entry.TextProperty,
                                  new Binding("Inker")
            {
                Mode = BindingMode.TwoWay
            });
            ColoristEntry.SetBinding(Entry.TextProperty,
                                     new Binding("Colorist")
            {
                Mode = BindingMode.TwoWay
            });
            LettererEntry.SetBinding(Entry.TextProperty,
                                     new Binding("Letterer")
            {
                Mode = BindingMode.TwoWay
            });
            EditorEntry.SetBinding(Entry.TextProperty,
                                   new Binding("Editor")
            {
                Mode = BindingMode.TwoWay
            });
            StoryTitleEntry.SetBinding(Entry.TextProperty,
                                       new Binding("StoryTitle")
            {
                Mode = BindingMode.TwoWay
            });
            CharacterEntry.SetBinding(Entry.TextProperty,
                                      new Binding("Character")
            {
                Mode = BindingMode.TwoWay
            });
            ISBNEntry.SetBinding(Entry.TextProperty,
                                 new Binding("ISBN")
            {
                Mode = BindingMode.TwoWay
            });
            BarcodeEntry.SetBinding(Entry.TextProperty,
                                    new Binding("Barcode")
            {
                Mode = BindingMode.TwoWay
            });
        }
示例#5
0
        public Stream CreateFile(string file, CompressionHint hint, DateTime lastWrite)
        {
            if(string.IsNullOrEmpty(file))
                throw new ArgumentNullException("file");

            if(m_writer == null)
                throw new InvalidOperationException(Strings.SevenZipCompression.NoWriterError);

            var entry = new WriterEntry(file, lastWrite);

            if(hint != CompressionHint.Noncompressible)
            {
                if(m_lzma2Encoder == null)
                {
                    if(m_lowOverheadMode)
                        m_lzma2Encoder = new ManagedLzma.LZMA.Master.SevenZip.ArchiveWriter.LzmaEncoder();
                    else
                        m_lzma2Encoder = new ManagedLzma.LZMA.Master.SevenZip.ArchiveWriter.Lzma2Encoder(m_threadCount);

                    m_lzma2Encoder.OnOutputThresholdReached += mLzma2Encoder_OnOutputThresholdReached;
                    m_lzma2Encoder.SetOutputThreshold(kStreamThreshold);
                }

                return m_lzma2Encoder.BeginWriteFile(entry);
            }
            else
            {
                if(m_copyEncoder == null)
                    m_copyEncoder = new ManagedLzma.LZMA.Master.SevenZip.ArchiveWriter.PlainEncoder();

                if(m_lzma2Encoder != null && m_lzma2Encoder == m_writer.CurrentEncoder)
                    m_lzma2Encoder.SetOutputThreshold(kStreamThreshold); // rearm threshold so we can switch back

                if(m_writer.CurrentEncoder != m_copyEncoder)
                    m_writer.ConnectEncoder(m_copyEncoder);

                return m_copyEncoder.BeginWriteFile(entry);
            }
        }
示例#6
0
文件: Channel.cs 项目: Danstahr/cocol
        /// <summary>
        /// Registers a desire to write to the channel
        /// </summary>
        /// <param name="offer">A callback method for offering an item, use null to unconditionally accept</param>
        /// <param name="value">The value to write to the channel.</param>
        /// <param name="timeout">The time to wait for the operation, use zero to return a timeout immediately if no items can be read. Use a negative span to wait forever.</param>
        public async Task WriteAsync(T value, TimeSpan timeout, ITwoPhaseOffer offer = null)
        {
            var wr = new WriterEntry(offer, new TaskCompletionSource <bool>(), timeout.Ticks <= 0 ? Timeout.InfiniteDateTime : DateTime.Now + timeout, value);

            using (await m_asynclock.LockAsync())
            {
                if (m_isRetired)
                {
                    ThreadPool.QueueItem(() => wr.Source.SetException(new RetiredException()));
                    await wr.Source.Task;
                    return;
                }

                m_writerQueue.Add(wr);
                if (!await MatchReadersAndWriters(false, wr.Source.Task))
                {
                    System.Diagnostics.Debug.Assert(m_writerQueue[m_writerQueue.Count - 1].Source == wr.Source);

                    // If we have a buffer slot to use
                    if (m_writerQueue.Count <= m_bufferSize && m_retireCount < 0)
                    {
                        if (offer == null || await offer.OfferAsync(this))
                        {
                            if (offer != null)
                            {
                                await offer.CommitAsync(this);
                            }

                            m_writerQueue[m_writerQueue.Count - 1] = new WriterEntry(null, null, Timeout.InfiniteDateTime, value);
                            wr.Source.TrySetResult(true);
                        }
                        else
                        {
                            wr.Source.TrySetCanceled();
                        }
                    }
                    else
                    {
                        // If this was a probe call, return a timeout now
                        if (timeout.Ticks >= 0 && wr.Expires < DateTime.Now)
                        {
                            m_writerQueue.RemoveAt(m_writerQueue.Count - 1);
                            ThreadPool.QueueItem(() => wr.Source.SetException(new TimeoutException()));
                        }
                        else
                        {
                            // Make room if we have too many
                            if (m_maxPendingWriters > 0 && (m_writerQueue.Count - m_bufferSize - 1) >= m_maxPendingWriters)
                            {
                                switch (m_pendingWritersOverflowStrategy)
                                {
                                case QueueOverflowStrategy.FIFO:
                                {
                                    var exp = m_writerQueue[m_bufferSize].Source;
                                    m_writerQueue.RemoveAt(m_bufferSize);
                                    if (exp != null)
                                    {
                                        ThreadPool.QueueItem(() => exp.TrySetException(new ChannelOverflowException()));
                                    }
                                }

                                break;

                                case QueueOverflowStrategy.LIFO:
                                {
                                    var exp = m_writerQueue[m_writerQueue.Count - 2].Source;
                                    m_writerQueue.RemoveAt(m_writerQueue.Count - 2);
                                    if (exp != null)
                                    {
                                        ThreadPool.QueueItem(() => exp.TrySetException(new ChannelOverflowException()));
                                    }
                                }

                                break;

                                case QueueOverflowStrategy.Reject:
                                default:
                                {
                                    var exp = m_writerQueue[m_writerQueue.Count - 1].Source;
                                    m_writerQueue.RemoveAt(m_writerQueue.Count - 1);
                                    if (exp != null)
                                    {
                                        ThreadPool.QueueItem(() => exp.TrySetException(new ChannelOverflowException()));
                                    }
                                    await wr.Source.Task;
                                }

                                    return;
                                }
                            }

                            // If we have expanded the queue with a new batch, see if we can purge old entries
                            m_writerQueueCleanup = await PerformQueueCleanupAsync(m_writerQueue, true, m_writerQueueCleanup);

                            if (wr.Expires != Timeout.InfiniteDateTime)
                            {
                                ExpirationManager.AddExpirationCallback(wr.Expires, () => ExpireItemsAsync().FireAndForget());
                            }
                        }
                    }
                }
            }

            await wr.Source.Task;

            return;
        }