/// <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)); } }
/// <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); }
/// <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 }); }
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); } }
/// <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; }