Conversation
…await # Conflicts: # src/SharpCompress/Archives/ArchiveFactory.Async.cs
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (X files)
|
There was a problem hiding this comment.
Pull request overview
This PR standardizes async behavior across SharpCompress by adding .ConfigureAwait(false) to awaited operations throughout archives/readers/writers and related helpers, aiming to avoid synchronization-context capture in library code.
Changes:
- Added
.ConfigureAwait(false)to awaited operations across archive/reader/writer async paths. - Updated async factory/detection logic to consistently avoid context capture.
- Adjusted several async iterator/helper implementations while applying the pattern.
Reviewed changes
Copilot reviewed 82 out of 82 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/SharpCompress/Writers/Tar/TarWriter.Async.cs | Add .ConfigureAwait(false) to delegated async write call. |
| src/SharpCompress/Writers/GZip/GZipWriter.Async.cs | Add .ConfigureAwait(false) to CopyToAsync awaits. |
| src/SharpCompress/Readers/ReaderFactory.Async.cs | Add .ConfigureAwait(false) to async factory probing/opening. |
| src/SharpCompress/Readers/Rar/RarReader.Async.cs | Add .ConfigureAwait(false) to multivolume stream creation await. |
| src/SharpCompress/Readers/Rar/MultiVolumeRarReader.Async.cs | Add .ConfigureAwait(false) to stream-load awaits. |
| src/SharpCompress/Readers/IAsyncReaderExtensions.cs | Add .ConfigureAwait(false) to MoveToNextEntryAsync in loop condition. |
| src/SharpCompress/Readers/Arj/ArjReader.cs | Add .ConfigureAwait(false) to header read awaits. |
| src/SharpCompress/Readers/Arc/ArcReader.Async.cs | Add .ConfigureAwait(false) to header read await in loop condition. |
| src/SharpCompress/Readers/Ace/AceReader.cs | Add .ConfigureAwait(false) to header read awaits. |
| src/SharpCompress/Readers/AbstractReader.Async.cs | Add .ConfigureAwait(false) to disposal/enumerator awaits; removed placeholder await in async iterator. |
| src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs | Add .ConfigureAwait(false) to enumerator awaits; removed placeholder awaits in async iterators. |
| src/SharpCompress/LazyAsyncReadOnlyCollection.cs | Add .ConfigureAwait(false) to source enumerator movement awaits. |
| src/SharpCompress/IO/SharpCompressStream.Async.cs | Add .ConfigureAwait(false) to read/write/dispose awaits in copy loop and disposal. |
| src/SharpCompress/Factories/ZipFactory.cs | Add .ConfigureAwait(false) to zip detection awaits. |
| src/SharpCompress/Factories/TarWrapper.cs | Add .ConfigureAwait(false) to wrapper stream creation awaits. |
| src/SharpCompress/Factories/TarFactory.cs | Add .ConfigureAwait(false) to wrapper match/decompress/tar-detect awaits. |
| src/SharpCompress/Factories/ArcFactory.cs | Add .ConfigureAwait(false) to ReadExactAsync await. |
| src/SharpCompress/Compressors/ZStandard/ZStandardStream.Async.cs | Add .ConfigureAwait(false) to header read await. |
| src/SharpCompress/Compressors/Rar/RarStream.Async.cs | Add .ConfigureAwait(false) to unpack initialization await. |
| src/SharpCompress/Compressors/Rar/RarCrcStream.Async.cs | Add .ConfigureAwait(false) to stream initialization await. |
| src/SharpCompress/Compressors/Rar/RarBLAKE2spStream.Async.cs | Add .ConfigureAwait(false) to stream initialization await. |
| src/SharpCompress/Compressors/Rar/MultiVolumeReadOnlyAsyncStream.Async.cs | Add .ConfigureAwait(false) to enumerator/dispose/move-next awaits. |
| src/SharpCompress/Compressors/Lzw/LzwStream.Async.cs | Add .ConfigureAwait(false) to header read await. |
| src/SharpCompress/Compressors/LZMA/Utilites/CrcBuilderStream.Async.cs | Add .ConfigureAwait(false) to target write await. |
| src/SharpCompress/Compressors/LZMA/LzmaStream.Async.cs | Add .ConfigureAwait(false) to init/train decoder awaits. |
| src/SharpCompress/Compressors/LZMA/LzmaDecoder.Async.cs | Add .ConfigureAwait(false) to decoder/bit-tree/literal decode awaits. |
| src/SharpCompress/Compressors/LZMA/LZipStream.Async.cs | Add .ConfigureAwait(false) to validation/write awaits. |
| src/SharpCompress/Compressors/LZMA/LZ/LzOutWindow.Async.cs | Add .ConfigureAwait(false) to init/release/train awaits. |
| src/SharpCompress/Compressors/LZMA/DecoderRegistry.Async.cs | Add .ConfigureAwait(false) to decoder stream creation awaits. |
| src/SharpCompress/Compressors/BZip2/CBZip2InputStream.Async.cs | Add .ConfigureAwait(false) to read/initialization awaits; removed placeholder await in an async method. |
| src/SharpCompress/Compressors/BZip2/BZip2Stream.Async.cs | Add .ConfigureAwait(false) to stream creation and header read awaits. |
| src/SharpCompress/Compressors/ADC/ADCStream.Async.cs | Add .ConfigureAwait(false) to decompression awaits. |
| src/SharpCompress/Compressors/ADC/ADCBase.Async.cs | Add .ConfigureAwait(false) to overload and stream read awaits. |
| src/SharpCompress/Common/Zip/ZipHeaderFactory.Async.cs | Add .ConfigureAwait(false) to header parsing awaits. |
| src/SharpCompress/Common/Zip/ZipFilePart.Async.cs | Add .ConfigureAwait(false) to decompressor creation awaits and recursive call await. |
| src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.Async.cs | Add .ConfigureAwait(false) to seek/read/header parse awaits. |
| src/SharpCompress/Common/Zip/SeekableZipFilePart.Async.cs | Add .ConfigureAwait(false) to local-header load and base call awaits. |
| src/SharpCompress/Common/Zip/Headers/Zip64DirectoryEndLocatorHeader.Async.cs | Add .ConfigureAwait(false) to primitive read awaits. |
| src/SharpCompress/Common/Zip/Headers/Zip64DirectoryEndHeader.Async.cs | Add .ConfigureAwait(false) to primitive/byte reads. |
| src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.Async.cs | Add .ConfigureAwait(false) to primitive/byte reads. |
| src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.Async.cs | Add .ConfigureAwait(false) to primitive/byte reads. |
| src/SharpCompress/Common/Zip/Headers/DirectoryEndHeader.Async.cs | Add .ConfigureAwait(false) to primitive/byte reads. |
| src/SharpCompress/Common/Tar/TarHeaderFactory.Async.cs | Add .ConfigureAwait(false) to tar header read await. |
| src/SharpCompress/Common/Tar/Headers/TarHeader.Async.cs | Add .ConfigureAwait(false) to tar read/write helper awaits. |
| src/SharpCompress/Common/SevenZip/SevenZipFilePart.cs | Add .ConfigureAwait(false) to folder stream/skip awaits. |
| src/SharpCompress/Common/SevenZip/ArchiveReader.Async.cs | Add .ConfigureAwait(false) to signature/header reads. |
| src/SharpCompress/Common/Rar/RarVolume.cs | Add .ConfigureAwait(false) to read/ensure header-load awaits. |
| src/SharpCompress/Common/Rar/Rar5CryptoInfo.cs | Add .ConfigureAwait(false) to async binary reader operations. |
| src/SharpCompress/Common/Rar/Headers/RarHeaderFactory.Async.cs | Add .ConfigureAwait(false) to crypt reader setup awaits. |
| src/SharpCompress/Common/Rar/Headers/FileHeader.Async.cs | Add .ConfigureAwait(false) to salt read await. |
| src/SharpCompress/Common/Rar/Headers/ArchiveCryptHeader.Async.cs | Add .ConfigureAwait(false) to crypto info creation await. |
| src/SharpCompress/Common/Rar/AsyncRarCryptoBinaryReader.cs | Add .ConfigureAwait(false) to salt read await. |
| src/SharpCompress/Common/GZip/GZipFilePart.Async.cs | Add .ConfigureAwait(false) to header/trailer/string read awaits. |
| src/SharpCompress/Common/GZip/GZipEntry.Async.cs | Add .ConfigureAwait(false) to part creation await. |
| src/SharpCompress/Common/Arj/Headers/ArjMainHeader.Async.cs | Add .ConfigureAwait(false) to header/extended header awaits. |
| src/SharpCompress/Common/Arj/Headers/ArjLocalHeader.Async.cs | Add .ConfigureAwait(false) to header/extended header awaits. |
| src/SharpCompress/Common/Arj/Headers/ArjHeader.Async.cs | Add .ConfigureAwait(false) to stream read awaits in header parsing and detection. |
| src/SharpCompress/Common/Arc/ArcFilePart.Async.cs | Add .ConfigureAwait(false) to squeezed stream creation await. |
| src/SharpCompress/Common/Arc/ArcEntryHeader.cs | Add .ConfigureAwait(false) to entry header read await. |
| src/SharpCompress/Common/Ace/Headers/AceMainHeader.Async.cs | Add .ConfigureAwait(false) to main header read await. |
| src/SharpCompress/Common/Ace/Headers/AceHeader.Async.cs | Add .ConfigureAwait(false) to header reads. |
| src/SharpCompress/Common/Ace/Headers/AceFileHeader.Async.cs | Add .ConfigureAwait(false) to file header read await. |
| src/SharpCompress/Archives/Zip/ZipArchiveEntry.Async.cs | Add .ConfigureAwait(false) to seekable compressed-stream await. |
| src/SharpCompress/Archives/Zip/ZipArchive.Factory.cs | Add .ConfigureAwait(false) to async header enumeration and async seekable header reads. |
| src/SharpCompress/Archives/Zip/ZipArchive.Async.cs | Add .ConfigureAwait(false) to volume list materialization await. |
| src/SharpCompress/Archives/Tar/TarArchiveEntry.cs | Add .ConfigureAwait(false) to compressed stream await. |
| src/SharpCompress/Archives/Tar/TarArchive.Factory.cs | Add .ConfigureAwait(false) to tar header read await. |
| src/SharpCompress/Archives/Tar/TarArchive.Async.cs | Add .ConfigureAwait(false) to volume selection and entry copy await. |
| src/SharpCompress/Archives/SevenZip/SevenZipArchiveEntry.cs | Add .ConfigureAwait(false) to compressed stream await. |
| src/SharpCompress/Archives/SevenZip/SevenZipArchive.Factory.cs | Add .ConfigureAwait(false) to signature match await. |
| src/SharpCompress/Archives/SevenZip/SevenZipArchive.Async.cs | Add .ConfigureAwait(false) to reader open/database load and volume selection awaits. |
| src/SharpCompress/Archives/Rar/RarArchiveEntry.Async.cs | Add .ConfigureAwait(false) to multivolume stream creation and init awaits. |
| src/SharpCompress/Archives/Rar/RarArchive.Extensions.cs | Add .ConfigureAwait(false) to first-volume retrieval awaits. |
| src/SharpCompress/Archives/Rar/RarArchive.Async.cs | Add .ConfigureAwait(false) to disposal, multipart checks, volume enumeration, and solid checks. |
| src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs | Add .ConfigureAwait(false) to AddEntryAsync await in file enumeration loop. |
| src/SharpCompress/Archives/IAsyncArchiveExtensions.cs | Add .ConfigureAwait(false) to IsSolidAsync, ExtractAllEntriesAsync, internal write, and size aggregation awaits. |
| src/SharpCompress/Archives/IArchiveEntryExtensions.cs | Add .ConfigureAwait(false) to OpenEntryStreamAsync awaits for both legacy and async-disposable paths. |
| src/SharpCompress/Archives/GZip/GZipArchive.Async.cs | Add .ConfigureAwait(false) to entry stream opens, volume selection, and file part creation awaits. |
| src/SharpCompress/Archives/ArchiveFactory.Async.cs | Add .ConfigureAwait(false) to factory discovery and delegated open awaits. |
| src/SharpCompress/Archives/AbstractWritableArchive.cs | Add .ConfigureAwait(false) to explicit interface async delegates. |
| src/SharpCompress/Archives/AbstractWritableArchive.Async.cs | Add .ConfigureAwait(false) to rebuild-modified-collection awaits. |
| src/SharpCompress/Archives/AbstractArchive.Async.cs | Add .ConfigureAwait(false) to volume materialization, lazy-load, solid checks, aggregate/all awaits. |
Comments suppressed due to low confidence (2)
src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs:27
ToAsyncEnumerableis stillasync IAsyncEnumerable<T>but now has noawait, which can trigger CS1998 and fail the build with warnings-as-errors. Restore the previous no-op await (withConfigureAwait(false)) or adjust the implementation so the async iterator contains at least one awaited operation.
src/SharpCompress/Readers/AbstractReader.Async.cs:208GetEntriesAsyncis an async iterator but now contains noawait(the previousTask.CompletedTaskplaceholder was removed). WithTreatWarningsAsErrors=true, this can trigger CS1998 and fail the build. Either restore a no-op awaited task (withConfigureAwait(false)) or refactor to avoid anasyncmethod body without awaits.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| byte[] crc = new byte[4]; | ||
| read = await stream.ReadAsync(crc, 0, 4, cancellationToken); | ||
| read = await stream.ReadAsync(crc, 0, 4, cancellationToken).ConfigureAwait(false); |
There was a problem hiding this comment.
This assignment to read is useless, since its value is never read.
| read = await stream.ReadAsync(crc, 0, 4, cancellationToken).ConfigureAwait(false); | |
| read = await stream.ReadAsync(crc, 0, 4, cancellationToken).ConfigureAwait(false); | |
| if (read < 4) | |
| { | |
| return Array.Empty<byte>(); | |
| } |
This pull request ensures consistent and correct asynchronous programming practices across the codebase by adding
.ConfigureAwait(false)to allawaitexpressions in asynchronous methods. This change improves reliability and prevents potential deadlocks, especially in library code that may be used in various synchronization contexts. The updates span multiple archive types and extension methods.The most important changes include:
Async Await Consistency and Reliability:
.ConfigureAwait(false)to allawaitexpressions in asynchronous methods throughoutAbstractArchive.Async.cs,AbstractWritableArchive.Async.cs,ArchiveFactory.Async.cs, and related files to prevent capturing the synchronization context and avoid deadlocks. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23]Archive Type-Specific Updates:
.ConfigureAwait(false)to all async operations in RAR and GZip archive classes and their extension methods, ensuring consistent asynchronous behavior across archive types. [1] [2] [3] [4]Extension Methods and Utility Updates:
WriteToAsync,WriteToDirectoryAsync, andAddEntryAsyncto use.ConfigureAwait(false)after all asynchronous calls. [1] [2] [3] [4] [5]These changes collectively make the async code safer and more predictable for consumers, especially in library and cross-platform scenarios.