//We do the close or the flush operation per part private void DoOperationOnEachPart(PartOperation operation) { //foreach (PackagePart p in _partList.Values) // p.Close(); - this throws // Make local copy of part names to prevent exception during enumeration when // a new relationship part gets created (flushing relationships can cause part creation). // This code throws in such a case: // // foreach (PackagePart p in _partList.Values) // p.Flush(); // if (_partList.Count > 0) { int partCount = 0; PackUriHelper.ValidatedPartUri[] partKeys = new PackUriHelper.ValidatedPartUri[_partList.Keys.Count]; foreach (PackUriHelper.ValidatedPartUri uri in _partList.Keys) { partKeys[partCount++] = uri; } // this throws an exception in certain cases (when a part has been deleted) // // _partList.Keys.CopyTo(keys, 0); for (int i = 0; i < _partList.Keys.Count; i++) { // Some of these may disappear during above close because the list contains "relationship parts" // and these are removed if their parts' relationship collection is empty // This fails: // _partList[keys[i]].Flush(); PackagePart p; if (_partList.TryGetValue(partKeys[i], out p)) { if (!operation(p)) break; } } } }
protected PackagePart(Package package, Uri partUri, string contentType, CompressionOption compressionOption) { this._compressionOption = CompressionOption.NotCompressed; if (package == null) { throw new ArgumentNullException("package"); } if (partUri == null) { throw new ArgumentNullException("partUri"); } Package.ThrowIfCompressionOptionInvalid(compressionOption); this._uri = PackUriHelper.ValidatePartUri(partUri); this._container = package; if (contentType == null) { this._contentType = null; } else { this._contentType = new ContentType(contentType); } this._requestedStreams = null; this._compressionOption = compressionOption; this._isRelationshipPart = PackUriHelper.IsRelationshipPartUri(partUri); }