最近我在函数应用程序中遇到了 OutOfMemoryExceptions。我已经把内存增加了好几次了。我开始怀疑内存泄漏,应用程序洞察指向绑定到 blob 存储的活动函数和仅运行存储过程并将结果写入 blob 存储的数据库提供程序。它将 blob 存储绑定到 TextWriter。 TextWriter实现了IDisposable,我想知道写完后是否需要处理掉它?
public static async Task<Response> ExecuteStoredProceedure(
[ActivityTrigger] Request request,
[Sql( CommandText = "{data.SprocData.FullProcName}",
CommandType = CommandType.StoredProcedure,
ConnectionString = "{data.DbConnectionString}",
CommandTimeout = "{data.Timeout}" )] SqlCommand cmd,
[Blob( "%TaskHubName%-largemessages/{data.SprocData.StoredProcName}" )] TextWriter writer )
{
cmd.Parameters.AddRange( request.Parameters.ToArray() );
await cmd.Connection.OpenAsync();
using var reader = await cmd.ExecuteReaderAsync();
var dt = new DataTable();
dt.Load( reader );
var rowCount = dt.Rows.Count;
await cmd.Connection.CloseAsync();
var json = JsonConvert.SerializeObject( dt );
await writer.WriteAsync( json );
return new Response( ColumnNames: dt.Columns.Select( c => c.ColumnName ), RowCount: rowCount );
}
既然TextWriter和SqlCommand都实现了IDisposable/IAsyncDispoable,我有责任处置它们吗?我在 Microsoft 文档中找不到任何处理 IDisposable 输入绑定的示例。但是,我见过使用隐式绑定来处理 IDisposable 的示例。
private static async Task WriteTransformedIndexerResultIntoBlob(IBinder binder, StringValues indexerId, string indexerInsights)
{
var outputContainer = Environment.GetEnvironmentVariable(VideoIndexerAppSettings.MediaIndexerStorageContainerAppSetting);
using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute($"{outputContainer}/{indexerId}.json")))
{
await writer.WriteAsync(indexerInsights);
await writer.FlushAsync();
}
}
我还编写了自定义绑定,但我不知道代码可以返回到 IConverter 以便它处理对象的任何方式。这表明如果我们不显式调用 writer.Dispose() 那么可能会导致内存泄漏。