Skip to content

Commit 80e043e

Browse files
committed
fix MemoryStream leaks + multi-attachments issue
1 parent b6056bc commit 80e043e

File tree

5 files changed

+34
-33
lines changed

5 files changed

+34
-33
lines changed

src/MaIN.InferPage/Components/Pages/Home.razor

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@
199199
private List<MessageExt> Messages { get; set; } = new();
200200
private ElementReference? _bottomElement;
201201
private ElementReference _editorRef;
202-
private List<IBrowserFile> _selectedFiles = new();
202+
private List<FileInfo> _selectedFiles = new();
203203
private int _inputKey;
204204

205205
private readonly MarkdownPipeline _markdownPipeline = new MarkdownPipelineBuilder()
@@ -271,17 +271,34 @@
271271
}
272272
}
273273

274-
private void HandleFileSelected(InputFileChangeEventArgs e)
274+
private async Task HandleFileSelected(InputFileChangeEventArgs e)
275275
{
276276
foreach (var file in e.GetMultipleFiles(10))
277277
{
278-
_selectedFiles.Add(file);
278+
var ms = new MemoryStream();
279+
try
280+
{
281+
await file.OpenReadStream(20 * 1024 * 1024).CopyToAsync(ms);
282+
ms.Position = 0;
283+
_selectedFiles.Add(new FileInfo
284+
{
285+
Name = file.Name,
286+
Extension = Path.GetExtension(file.Name),
287+
StreamContent = ms
288+
});
289+
}
290+
catch (Exception ex)
291+
{
292+
await ms.DisposeAsync();
293+
_errorMessage = $"Failed to read file {file.Name}: {ex.Message}";
294+
}
279295
}
280296
StateHasChanged();
281297
}
282298

283-
private void RemoveFile(IBrowserFile file)
299+
private void RemoveFile(FileInfo file)
284300
{
301+
file.StreamContent?.Dispose();
285302
_selectedFiles.Remove(file);
286303
}
287304

@@ -304,29 +321,9 @@
304321
_isLoading = true;
305322
StateHasChanged();
306323

324+
var attachments = new List<FileInfo>(_selectedFiles);
307325
try
308326
{
309-
var attachments = new List<FileInfo>();
310-
foreach (var file in _selectedFiles)
311-
{
312-
try
313-
{
314-
var ms = new MemoryStream();
315-
await file.OpenReadStream(20 * 1024 * 1024).CopyToAsync(ms, cancellationToken);
316-
ms.Position = 0;
317-
attachments.Add(new FileInfo
318-
{
319-
Name = file.Name,
320-
Extension = Path.GetExtension(file.Name),
321-
StreamContent = ms
322-
});
323-
}
324-
catch (Exception ex)
325-
{
326-
_errorMessage = $"Failed to read file {file.Name}: {ex.Message}";
327-
}
328-
}
329-
330327
_selectedFiles.Clear();
331328
_inputKey++;
332329
StateHasChanged();
@@ -445,6 +442,10 @@
445442
}
446443
finally
447444
{
445+
foreach (var attachment in attachments)
446+
attachment.StreamContent?.Dispose();
447+
attachments.Clear();
448+
448449
_isLoading = false;
449450
_isThinking = false;
450451
StateHasChanged();

src/MaIN.Services/Services/LLMService/DeepSeekService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protected override void ValidateApiKey()
5757
CancellationToken cancellationToken = default)
5858
{
5959
var lastMsg = chat.Messages.Last();
60-
var filePaths = await DocumentProcessor.ConvertToFilesContent(memoryOptions);
60+
var filePaths = await DocumentProcessor.ConvertToFilesContent(memoryOptions, cancellationToken);
6161
var message = new Message()
6262
{
6363
Role = ServiceConstants.Roles.User,

src/MaIN.Services/Services/LLMService/GroqCloudService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected override void ValidateApiKey()
5151
CancellationToken cancellationToken = default)
5252
{
5353
var lastMsg = chat.Messages.Last();
54-
var filePaths = await DocumentProcessor.ConvertToFilesContent(memoryOptions);
54+
var filePaths = await DocumentProcessor.ConvertToFilesContent(memoryOptions, cancellationToken);
5555
var message = new Message()
5656
{
5757
Role = ServiceConstants.Roles.User,

src/MaIN.Services/Services/LLMService/Memory/DocumentProcessor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static string ProcessDocument(string filePath)
3131
};
3232
}
3333

34-
public static async Task<string[]> ConvertToFilesContent(ChatMemoryOptions options)
34+
public static async Task<string[]> ConvertToFilesContent(ChatMemoryOptions options, CancellationToken cancellationToken = default)
3535
{
3636
var files = new List<string>();
3737
foreach (var fData in options.FilesData)
@@ -43,14 +43,14 @@ public static async Task<string[]> ConvertToFilesContent(ChatMemoryOptions optio
4343
{
4444
var path = Path.Combine(Path.GetTempPath(), sData.Key);
4545
await using var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
46-
await sData.Value.CopyToAsync(fileStream);
46+
await sData.Value.CopyToAsync(fileStream, cancellationToken);
4747
files.Add(path);
4848
}
4949

5050
foreach (var txt in options.TextData)
5151
{
5252
var path = Path.Combine(Path.GetTempPath(), $"{txt.Key}.txt");
53-
await File.WriteAllTextAsync(path, txt.Value);
53+
await File.WriteAllTextAsync(path, txt.Value, cancellationToken);
5454
files.Add(path);
5555
}
5656

@@ -60,8 +60,8 @@ public static async Task<string[]> ConvertToFilesContent(ChatMemoryOptions optio
6060
foreach (var web in options.WebUrls)
6161
{
6262
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.html");
63-
var html = await client.GetStringAsync(web);
64-
await File.WriteAllTextAsync(path, html);
63+
var html = await client.GetStringAsync(web, cancellationToken);
64+
await File.WriteAllTextAsync(path, html, cancellationToken);
6565
files.Add(path);
6666
}
6767
}

src/MaIN.Services/Services/LLMService/XaiService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected override void ValidateApiKey()
5050
CancellationToken cancellationToken = default)
5151
{
5252
var lastMsg = chat.Messages.Last();
53-
var filePaths = await DocumentProcessor.ConvertToFilesContent(memoryOptions);
53+
var filePaths = await DocumentProcessor.ConvertToFilesContent(memoryOptions, cancellationToken);
5454
var message = new Message()
5555
{
5656
Role = ServiceConstants.Roles.User,

0 commit comments

Comments
 (0)