Skip to content

Commit f0238ae

Browse files
Revised and patched the workflow for exporting to OpenXml asynchronously
- Added missing DisposeAsync calls in OpenXmlWriter, and implemented IAsyncDisposable interface in SheetStyleBuildContext and EnhancedStreamWriter - Removed manual duplication of synchronous methods from SheetStyleBuildContext - Removed superfluous MiniExcelZipArchive class - Renamed EnhancedStreamWriter to MiniExcelStreamWriter and changed internal StreamWriter initialization to leave underlying stream open to avoid synchronous disposal
1 parent b2ecec2 commit f0238ae

6 files changed

Lines changed: 185 additions & 251 deletions

File tree

src/MiniExcel.Core/Helpers/EnhancedStreamWriter.cs

Lines changed: 0 additions & 65 deletions
This file was deleted.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
namespace MiniExcelLib.Core.Helpers;
2+
3+
public sealed partial class MiniExcelStreamWriter(Stream stream, Encoding encoding, int bufferSize) : IDisposable
4+
#if NET8_0_OR_GREATER
5+
, IAsyncDisposable
6+
#endif
7+
{
8+
// if leaveOpen is set to false, the StreamWriter closes the underlying stream synchronously in a finally block.
9+
// Since we want to avoid all synchronous operations when dealing with streams we leave it open here, as it will disposed from the caller anyways
10+
private readonly StreamWriter _streamWriter = new(stream, encoding, bufferSize, true);
11+
private bool _disposed;
12+
13+
[CreateSyncVersion]
14+
public async Task WriteAsync(string content, CancellationToken cancellationToken = default)
15+
{
16+
if (!string.IsNullOrEmpty(content))
17+
{
18+
#if NET8_0_OR_GREATER
19+
await _streamWriter.WriteAsync(content.AsMemory(), cancellationToken)
20+
#else
21+
cancellationToken.ThrowIfCancellationRequested();
22+
await _streamWriter.WriteAsync(content)
23+
#endif
24+
.ConfigureAwait(false);
25+
}
26+
}
27+
28+
[CreateSyncVersion]
29+
public async Task<long> WriteAndFlushAsync(string content, CancellationToken cancellationToken = default)
30+
{
31+
await WriteAsync(content, cancellationToken).ConfigureAwait(false);
32+
return await FlushAndGetPositionAsync(cancellationToken).ConfigureAwait(false);
33+
}
34+
35+
[CreateSyncVersion]
36+
public async Task<long> FlushAndGetPositionAsync(CancellationToken cancellationToken = default)
37+
{
38+
await _streamWriter.FlushAsync(
39+
#if NET8_0_OR_GREATER
40+
cancellationToken
41+
#endif
42+
).ConfigureAwait(false);
43+
return _streamWriter.BaseStream.Position;
44+
}
45+
46+
public void SetPosition(long position)
47+
{
48+
_streamWriter.BaseStream.Position = position;
49+
}
50+
51+
public void Dispose()
52+
{
53+
if (!_disposed)
54+
{
55+
_streamWriter.Dispose();
56+
_disposed = true;
57+
}
58+
}
59+
60+
#if NET8_0_OR_GREATER
61+
public async ValueTask DisposeAsync()
62+
{
63+
if (!_disposed)
64+
{
65+
await _streamWriter.DisposeAsync().ConfigureAwait(false);
66+
_disposed = true;
67+
}
68+
}
69+
#endif
70+
}

0 commit comments

Comments
 (0)